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 lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data, True, False};
import util::filesearch;
import middle::ast_map::{path, path_mod, path_name};
enum output_type {
output_type_none,
@ -514,25 +515,27 @@ fn get_symbol_hash(ccx: @crate_ctxt, t: ty::t) -> str {
ret hash;
}
fn mangle(ss: [str]) -> str {
fn mangle(ss: path) -> str {
// Follow C++ namespace-mangling style
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.
ret n;
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
ret mangle(path + [hash]); // + "@" + vers;
ret mangle(path + [path_name(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);
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 {
let s = util::ppaux::ty_to_short_str(ccx.tcx, 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 {
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);
}

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, "");
ecx.ccx.ast_map.items {|key, val|
alt val {
middle::ast_map::node_item(i) {
middle::ast_map::node_item(i, _) {
index += [{val: key, pos: ebml_w.writer.tell()}];
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()}];
encode_info_for_native_item(ecx, ebml_w, i);
}

View File

@ -4,10 +4,13 @@ import syntax::ast::*;
import syntax::ast_util;
import syntax::{visit, codemap};
enum path_elt { path_mod(str), path_name(str) }
type path = [path_elt];
enum ast_node {
node_item(@item),
node_native_item(@native_item),
node_method(@method),
node_item(@item, @path),
node_native_item(@native_item, @path),
node_method(@method, @path),
node_expr(@expr),
// Locals are numbered, because the alias analysis needs to know in which
// order they are introduced.
@ -17,66 +20,78 @@ enum 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 {
let cx = @{map: std::map::new_int_hash(),
mutable local_id: 0u};
let v_map = visit::mk_simple_visitor
(@{visit_item: bind map_item(cx, _),
visit_native_item: bind map_native_item(cx, _),
visit_expr: bind map_expr(cx, _),
visit_fn: bind map_fn(cx, _, _, _, _, _),
visit_local: bind map_local(cx, _),
visit_arm: bind map_arm(cx, _)
with *visit::default_simple_visitor()});
visit::visit_crate(c, (), v_map);
let cx = {map: std::map::new_int_hash(),
mutable path: [],
mutable local_id: 0u};
visit::visit_crate(c, cx, visit::mk_vt(@{
visit_item: map_item,
visit_native_item: map_native_item,
visit_expr: map_expr,
visit_fn: map_fn,
visit_local: map_local,
visit_arm: map_arm
with *visit::default_visitor()
}));
ret cx.map;
}
fn map_fn(cx: ctx, _fk: visit::fn_kind, decl: fn_decl, _body: blk,
_sp: codemap::span, _id: node_id) {
fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
sp: codemap::span, id: node_id, cx: ctx, v: vt) {
for a in decl.inputs {
cx.map.insert(a.id, node_arg(a, cx.local_id));
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|
cx.map.insert(p_id, node_local(cx.local_id));
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|
cx.map.insert(p_id, node_local(cx.local_id));
cx.local_id += 1u;
};
visit::visit_arm(arm, cx, v);
}
fn map_item(cx: ctx, i: @item) {
cx.map.insert(i.id, node_item(i));
fn map_item(i: @item, cx: ctx, v: vt) {
cx.map.insert(i.id, node_item(i, @cx.path));
alt i.node {
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) {
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) {
cx.map.insert(i.id, node_native_item(i));
fn map_native_item(i: @native_item, cx: ctx, v: vt) {
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));
visit::visit_expr(ex, cx, v);
}
// 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));
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 {
ast::item_fn(decl, _, _) | ast::item_res(decl, _, _, _, _) {
(item.ident, decl.output, item.id)
@ -770,7 +770,7 @@ fn create_function(fcx: @fn_ctxt) -> @metadata<subprogram_md> {
bound to non-function"); }
}
}
ast_map::node_method(method) {
ast_map::node_method(method, _) {
(method.ident, method.decl.output, method.id)
}
ast_map::node_res_ctor(item) {
@ -808,7 +808,7 @@ fn create_function(fcx: @fn_ctxt) -> @metadata<subprogram_md> {
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,
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?
alt fk {
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
// as the main ID
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;
}
//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 {
// 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

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,
vdefs: {enm: def_id, var: def_id}, val: ValueRef) ->
{vals: [ValueRef], bcx: @block_ctxt} {
let ccx = bcx.fcx.lcx.ccx, bcx = bcx;
let ccx = bcx.fcx.ccx, bcx = bcx;
// invariant:
// 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);
@ -412,7 +412,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
let vals_left =
vec::slice(vals, 0u, col) +
vec::slice(vals, col + 1u, vec::len(vals));
let ccx = bcx.fcx.lcx.ccx;
let ccx = bcx.fcx.ccx;
let pat_id = 0;
for br: match_branch in m {
// 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 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);
compile_submatch(vr.bcx, match, [vr.val],
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
fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
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
alt normalize_pat(bcx_tcx(bcx), pat).node {

View File

@ -24,6 +24,7 @@ import front::attr;
import middle::freevars::*;
import back::{link, abi, upcall};
import syntax::{ast, ast_util, codemap};
import ast_util::local_def;
import syntax::visit;
import syntax::codemap::span;
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 common::*;
import build::*;
import ast_map::{path, path_mod, path_name};
fn type_of_1(bcx: @block_ctxt, t: ty::t) -> TypeRef {
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,
tpt: ty::ty_param_bounds_and_ty) -> TypeRef {
let cx = lcx.ccx;
fn type_of_ty_param_bounds_and_ty
(ccx: @crate_ctxt, tpt: ty::ty_param_bounds_and_ty) -> TypeRef {
let t = tpt.ty;
alt ty::struct(cx.tcx, t) {
alt ty::struct(ccx.tcx, t) {
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
@ -237,8 +238,8 @@ fn type_of_ty_param_bounds_and_ty(lcx: @local_ctxt,
// FIXME: could have a precondition on tpt, but that
// doesn't work right now because one predicate can't imply
// another
check (type_has_static_size(cx, t));
type_of(cx, t)
check type_has_static_size(ccx, t);
type_of(ccx, t)
}
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>,
llmod: ModuleRef,
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 output = ccx.int_type;
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; }
none {
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);
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);
}
fn set_glue_inlining(cx: @local_ctxt, f: ValueRef, t: ty::t) {
if ty::type_is_structural(cx.ccx.tcx, t) {
fn set_glue_inlining(ccx: @crate_ctxt, f: ValueRef, t: ty::t) {
if ty::type_is_structural(ccx.tcx, t) {
set_no_inline(f);
} else { set_always_inline(f); }
}
// 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 {
log(debug, "+++ declare_tydesc " + ty_to_str(cx.ccx.tcx, t));
let ccx = cx.ccx;
log(debug, "+++ declare_tydesc " + ty_to_str(ccx.tcx, t));
let llsize;
let llalign;
if check type_has_static_size(ccx, t) {
@ -1030,63 +1030,59 @@ fn declare_tydesc(cx: @local_ctxt, t: ty::t, ty_params: [uint])
llalign = C_int(ccx, 0);
}
let name;
if cx.ccx.sess.opts.debuginfo {
name = mangle_internal_name_by_type_only(cx.ccx, t, "tydesc");
if ccx.sess.opts.debuginfo {
name = mangle_internal_name_by_type_only(ccx, t, "tydesc");
name = sanitize(name);
} else { name = mangle_internal_name_by_seq(cx.ccx, "tydesc"); }
let gvar =
str::as_buf(name,
{|buf|
llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf)
});
} else { name = mangle_internal_name_by_seq(ccx, "tydesc"); }
let gvar = str::as_buf(name, {|buf|
llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf)
});
let info =
@{ty: t,
tydesc: gvar,
size: llsize,
align: llalign,
mutable take_glue: none::<ValueRef>,
mutable drop_glue: none::<ValueRef>,
mutable free_glue: none::<ValueRef>,
mutable cmp_glue: none::<ValueRef>,
mutable take_glue: none,
mutable drop_glue: none,
mutable free_glue: none,
mutable cmp_glue: none,
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;
}
type glue_helper = fn@(@block_ctxt, ValueRef, ty::t);
fn declare_generic_glue(cx: @local_ctxt, t: ty::t, llfnty: TypeRef, name: str)
-> ValueRef {
fn declare_generic_glue(ccx: @crate_ctxt, t: ty::t, llfnty: TypeRef,
name: str) -> ValueRef {
let name = name;
let fn_nm;
if cx.ccx.sess.opts.debuginfo {
fn_nm = mangle_internal_name_by_type_only(cx.ccx, t, "glue_" + name);
if ccx.sess.opts.debuginfo {
fn_nm = mangle_internal_name_by_type_only(ccx, t, "glue_" + name);
fn_nm = sanitize(fn_nm);
} else { fn_nm = mangle_internal_name_by_seq(cx.ccx, "glue_" + name); }
let llfn = decl_cdecl_fn(cx.ccx.llmod, fn_nm, llfnty);
set_glue_inlining(cx, llfn, t);
} else { fn_nm = mangle_internal_name_by_seq(ccx, "glue_" + name); }
let llfn = decl_cdecl_fn(ccx.llmod, fn_nm, llfnty);
set_glue_inlining(ccx, llfn, t);
ret llfn;
}
// 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,
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);
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
// requirement since in many contexts glue is invoked indirectly and
// the caller has no idea if it's dealing with something that can be
// passed by value.
let ccx = cx.ccx;
let llty =
if check type_has_static_size(ccx, t) {
T_ptr(type_of(ccx, t))
} else { T_ptr(T_i8()) };
let llty = if check type_has_static_size(ccx, t) {
T_ptr(type_of(ccx, t))
} 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 load_env_bcx = new_raw_block_ctxt(fcx, fcx.llloadenv);
let lltydescs = [mutable];
@ -1109,17 +1105,17 @@ fn make_generic_glue_inner(cx: @local_ctxt, t: ty::t,
ret llfn;
}
fn make_generic_glue(cx: @local_ctxt, t: ty::t, llfn: ValueRef,
helper: glue_helper, ty_params: [uint], name: str) ->
ValueRef {
if !cx.ccx.sess.opts.stats {
ret make_generic_glue_inner(cx, t, llfn, helper, ty_params);
fn make_generic_glue(ccx: @crate_ctxt, t: ty::t, llfn: ValueRef,
helper: glue_helper, ty_params: [uint], name: str)
-> ValueRef {
if !ccx.sess.opts.stats {
ret make_generic_glue_inner(ccx, t, llfn, helper, ty_params);
}
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();
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);
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,
static_ti: option<@tydesc_info>) {
let ccx = cx.fcx.ccx;
alt static_ti {
none { }
some(ti) {
@ -1655,12 +1652,10 @@ fn lazily_emit_tydesc_glue(cx: @block_ctxt, field: int,
none {
#debug("+++ lazily_emit_tydesc_glue TAKE %s",
ty_to_str(bcx_tcx(cx), ti.ty));
let lcx = cx.fcx.lcx;
let glue_fn =
declare_generic_glue(lcx, ti.ty, T_glue_fn(lcx.ccx),
"take");
ti.take_glue = some::<ValueRef>(glue_fn);
make_generic_glue(lcx, ti.ty, glue_fn,
let glue_fn = declare_generic_glue
(ccx, ti.ty, T_glue_fn(ccx), "take");
ti.take_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_take_glue,
ti.ty_params, "take");
#debug("--- lazily_emit_tydesc_glue TAKE %s",
@ -1673,12 +1668,10 @@ fn lazily_emit_tydesc_glue(cx: @block_ctxt, field: int,
none {
#debug("+++ lazily_emit_tydesc_glue DROP %s",
ty_to_str(bcx_tcx(cx), ti.ty));
let lcx = cx.fcx.lcx;
let glue_fn =
declare_generic_glue(lcx, ti.ty, T_glue_fn(lcx.ccx),
"drop");
ti.drop_glue = some::<ValueRef>(glue_fn);
make_generic_glue(lcx, ti.ty, glue_fn,
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "drop");
ti.drop_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_drop_glue,
ti.ty_params, "drop");
#debug("--- lazily_emit_tydesc_glue DROP %s",
@ -1691,12 +1684,10 @@ fn lazily_emit_tydesc_glue(cx: @block_ctxt, field: int,
none {
#debug("+++ lazily_emit_tydesc_glue FREE %s",
ty_to_str(bcx_tcx(cx), ti.ty));
let lcx = cx.fcx.lcx;
let glue_fn =
declare_generic_glue(lcx, ti.ty, T_glue_fn(lcx.ccx),
"free");
ti.free_glue = some::<ValueRef>(glue_fn);
make_generic_glue(lcx, ti.ty, glue_fn,
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "free");
ti.free_glue = some(glue_fn);
make_generic_glue(ccx, ti.ty, glue_fn,
make_free_glue,
ti.ty_params, "free");
#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,
tpt: ty::ty_param_bounds_and_ty) -> ValueRef {
let lcx = cx.fcx.lcx;
let name = csearch::get_symbol(lcx.ccx.sess.cstore, did);
ret get_extern_const(lcx.ccx.externs, lcx.ccx.llmod, name,
type_of_ty_param_bounds_and_ty(lcx, tpt));
let ccx = cx.fcx.ccx;
let name = csearch::get_symbol(ccx.sess.cstore, did);
ret get_extern_const(ccx.externs, ccx.llmod, name,
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)
@ -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};
}
fn lookup_discriminant(lcx: @local_ctxt, vid: ast::def_id) -> ValueRef {
let ccx = lcx.ccx;
fn lookup_discriminant(ccx: @crate_ctxt, vid: ast::def_id) -> ValueRef {
alt ccx.discrims.find(vid) {
none {
// It's an external discriminant that we haven't seen yet.
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|
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
});
lib::llvm::SetLinkage(gvar, lib::llvm::ExternalLinkage);
llvm::LLVMSetGlobalConstant(gvar, True);
lcx.ccx.discrims.insert(vid, gvar);
ccx.discrims.insert(vid, gvar);
ret gvar;
}
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 llenumptr = PointerCast(bcx, llenumblob, T_ptr(llenumty));
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);
Store(bcx, lldiscrim, lldiscrimptr);
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,
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 addr = alt dest {
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 {
let ccx = bcx_ccx(cx);
let lcx = cx.fcx.lcx;
let tcx = ccx.tcx;
let modname = str::connect(lcx.module_path, "::");
let ccx = bcx_ccx(cx), tcx = ccx.tcx;
if ty::type_is_bot(tcx, ty::expr_ty(tcx, lvl)) {
ret trans_expr(cx, lvl, ignore);
}
let global = if lcx.ccx.module_data.contains_key(modname) {
lcx.ccx.module_data.get(modname)
let modpath = vec::filter(cx.fcx.path, {|e|
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 {
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|
llvm::LLVMAddGlobal(lcx.ccx.llmod, T_i32(), buf)
llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf)
});
llvm::LLVMSetGlobalConstant(global, False);
llvm::LLVMSetInitializer(global, C_null(T_i32()));
lib::llvm::SetLinkage(global, lib::llvm::InternalLinkage);
lcx.ccx.module_data.insert(modname, global);
ccx.module_data.insert(modname, global);
global
};
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"); }
@ -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,
name: str, block_span: option<span>) -> @block_ctxt {
let s = "";
if cx.lcx.ccx.sess.opts.save_temps ||
cx.lcx.ccx.sess.opts.debuginfo {
s = cx.lcx.ccx.names(name);
if cx.ccx.sess.opts.save_temps || cx.ccx.sess.opts.debuginfo {
s = cx.ccx.names(name);
}
let llbb: BasicBlockRef =
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;
}
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,
// derived tydescs, and dynamic allocas.
fn mk_standard_basic_blocks(llfn: ValueRef) ->
@ -4318,8 +4300,8 @@ fn mk_standard_basic_blocks(llfn: ValueRef) ->
// - create_llargs_for_fn_args.
// - new_fn_ctxt
// - trans_args
fn new_fn_ctxt_w_id(cx: @local_ctxt, llfndecl: ValueRef,
id: ast::node_id, rstyle: ast::ret_style,
fn new_fn_ctxt_w_id(ccx: @crate_ctxt, path: path,
llfndecl: ValueRef, id: ast::node_id,
sp: option<span>) -> @fn_ctxt {
let llbbs = mk_standard_basic_blocks(llfndecl);
ret @{llfn: llfndecl,
@ -4339,14 +4321,14 @@ fn new_fn_ctxt_w_id(cx: @local_ctxt, llfndecl: ValueRef,
mutable lltyparams: [],
derived_tydescs: ty::new_ty_hash(),
id: id,
ret_style: rstyle,
span: sp,
lcx: cx};
path: path,
ccx: ccx};
}
fn new_fn_ctxt(cx: @local_ctxt, llfndecl: ValueRef, sp: option<span>)
-> @fn_ctxt {
ret new_fn_ctxt_w_id(cx, llfndecl, -1, ast::return_val, sp);
fn new_fn_ctxt(ccx: @crate_ctxt, path: path, llfndecl: ValueRef,
sp: option<span>) -> @fn_ctxt {
ret new_fn_ctxt_w_id(ccx, path, llfndecl, -1, sp);
}
// 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.
// If the function closes over its environment a closure will be
// 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,
ty_self: self_arg, ty_params: [ast::ty_param],
id: ast::node_id, maybe_load_env: fn(@fn_ctxt)) {
set_uwtable(llfndecl);
// 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 the first basic block in the function and keep a handle on it to
// pass to finish_fn later.
let bcx = new_top_block_ctxt(fcx, some(body.span));
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);
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_block, trans_expr, et cetera).
if option::is_none(body.node.expr) ||
ty::type_is_bot(cx.ccx.tcx, block_ty) ||
ty::type_is_nil(cx.ccx.tcx, block_ty) {
ty::type_is_bot(ccx.tcx, block_ty) ||
ty::type_is_nil(ccx.tcx, block_ty) {
bcx = trans_block(bcx, body);
} else {
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
// function.
fn trans_fn(cx: @local_ctxt, decl: ast::fn_decl, body: ast::blk,
llfndecl: ValueRef, ty_self: self_arg, ty_params: [ast::ty_param],
id: ast::node_id) {
let do_time = cx.ccx.sess.opts.stats;
fn trans_fn(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
body: ast::blk, llfndecl: ValueRef, ty_self: self_arg,
ty_params: [ast::ty_param], id: ast::node_id) {
let do_time = ccx.sess.opts.stats;
let start = if do_time {
time::get_time()
} else {
{sec: 0u32, usec: 0u32}
};
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);});
if cx.ccx.sess.opts.extra_debuginfo {
if ccx.sess.opts.extra_debuginfo {
debuginfo::create_function(option::get(fcx));
}
if do_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]) {
let ccx = cx.ccx;
// Create a function for the constructor
let llctor_decl = ccx.item_ids.get(ctor_id);
let fcx = new_fn_ctxt(cx, llctor_decl, none);
let ret_t = ty::ret_ty_of_fn(cx.ccx.tcx, ctor_id);
let fcx = new_fn_ctxt_w_id(ccx, path, llctor_decl, ctor_id, none);
let ret_t = ty::ret_ty_of_fn(ccx.tcx, ctor_id);
create_llargs_for_fn_args(fcx, no_self, dtor.inputs, ty_params);
let bcx = new_top_block_ctxt(fcx, none);
let lltop = bcx.llbb;
@ -4574,25 +4554,21 @@ fn trans_res_ctor(cx: @local_ctxt, dtor: ast::fn_decl,
}
fn trans_enum_variant(cx: @local_ctxt, enum_id: ast::node_id,
variant: ast::variant, disr: int, is_degen: bool,
ty_params: [ast::ty_param]) {
let ccx = cx.ccx;
if vec::len::<ast::variant_arg>(variant.node.args) == 0u {
fn trans_enum_variant(ccx: @crate_ctxt,
enum_id: ast::node_id,
variant: ast::variant, disr: int, is_degen: bool,
ty_params: [ast::ty_param]) {
if vec::len(variant.node.args) == 0u {
ret; // nullary constructors are just constants
}
// Translate variant arguments to function arguments.
let fn_args: [ast::arg] = [];
let i = 0u;
for varg: ast::variant_arg in variant.node.args {
fn_args +=
[{mode: ast::by_copy,
ty: varg.ty,
ident: "arg" + uint::to_str(i, 10u),
id: varg.id}];
// Translate variant arguments to function arguments.
let fn_args = [], i = 0u;
for varg in variant.node.args {
fn_args += [{mode: ast::by_copy,
ty: varg.ty,
ident: "arg" + uint::to_str(i, 10u),
id: varg.id}];
}
assert (ccx.item_ids.contains_key(variant.node.id));
let llfndecl: ValueRef;
@ -4600,16 +4576,15 @@ fn trans_enum_variant(cx: @local_ctxt, enum_id: ast::node_id,
some(x) { llfndecl = x; }
_ {
ccx.sess.span_fatal(variant.span,
"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);
let ty_param_substs: [ty::t] = [];
i = 0u;
let ty_param_substs = [], i = 0u;
for tp: ast::ty_param in ty_params {
ty_param_substs += [ty::mk_param(ccx.tcx, i,
ast_util::local_def(tp.id))];
local_def(tp.id))];
i += 1u;
}
let arg_tys = arg_tys_of_fn(ccx, variant.node.id);
@ -4618,19 +4593,18 @@ fn trans_enum_variant(cx: @local_ctxt, enum_id: ast::node_id,
bcx = copy_args_to_allocas(fcx, bcx, fn_args, arg_tys);
// Cast the enum to a type we can GEP into.
let llblobptr =
if is_degen {
fcx.llretptr
} else {
let llenumptr =
PointerCast(bcx, fcx.llretptr, T_opaque_enum_ptr(ccx));
let lldiscrimptr = GEPi(bcx, llenumptr, [0, 0]);
Store(bcx, C_int(ccx, disr), lldiscrimptr);
GEPi(bcx, llenumptr, [0, 1])
};
i = 0u;
let t_id = ast_util::local_def(enum_id);
let v_id = ast_util::local_def(variant.node.id);
let llblobptr = if is_degen {
fcx.llretptr
} else {
let llenumptr =
PointerCast(bcx, fcx.llretptr, T_opaque_enum_ptr(ccx));
let lldiscrimptr = GEPi(bcx, llenumptr, [0, 0]);
Store(bcx, C_int(ccx, disr), lldiscrimptr);
GEPi(bcx, llenumptr, [0, 1])
};
let i = 0u;
let t_id = local_def(enum_id);
let v_id = local_def(variant.node.id);
for va: ast::variant_arg in variant.node.args {
check (valid_variant_index(i, bcx, t_id, v_id));
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
// function itself is unnecessary). We used to do this, in fact, and will
// perhaps do so in the future.
fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod,
abi: ast::native_abi) {
fn build_shim_fn(lcx: @local_ctxt,
fn trans_native_mod(ccx: @crate_ctxt,
native_mod: ast::native_mod, abi: ast::native_abi) {
fn build_shim_fn(ccx: @crate_ctxt,
native_item: @ast::native_item,
tys: @c_stack_tys,
cc: lib::llvm::CallConv) -> ValueRef {
let lname = link_name(native_item);
let ccx = lcx_ccx(lcx);
// Declare the "prototype" for the base function F:
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);
// 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 lltop = bcx.llbb;
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;
}
fn build_wrap_fn(lcx: @local_ctxt,
fn build_wrap_fn(ccx: @crate_ctxt,
tys: @c_stack_tys,
num_tps: uint,
llshimfn: ValueRef,
llwrapfn: ValueRef) {
let ccx = lcx_ccx(lcx);
let fcx = new_fn_ctxt(lcx, llwrapfn, none);
let fcx = new_fn_ctxt(ccx, [], llwrapfn, none);
let bcx = new_top_block_ctxt(fcx, none);
let lltop = bcx.llbb;
@ -4894,7 +4866,6 @@ fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod,
finish_fn(fcx, lltop);
}
let ccx = lcx_ccx(lcx);
let cc = lib::llvm::CCallConv;
alt abi {
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);
alt ccx.item_ids.find(id) {
some(llwrapfn) {
let llshimfn = build_shim_fn(lcx, native_item, tys, cc);
build_wrap_fn(lcx, tys, vec::len(tps), llshimfn, llwrapfn);
let llshimfn = build_shim_fn(ccx, native_item, tys, cc);
build_wrap_fn(ccx, tys, vec::len(tps), llshimfn, llwrapfn);
}
none {
ccx.sess.span_fatal(
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 {
ast::item_fn(decl, tps, body) {
let sub_cx = extend_path(cx, item.ident);
alt cx.ccx.item_ids.find(item.id) {
alt ccx.item_ids.find(item.id) {
some(llfndecl) {
trans_fn(sub_cx, decl, body, llfndecl, no_self, tps,
item.id);
trans_fn(ccx, *path + [path_name(item.ident)], decl, body,
llfndecl, no_self, tps, item.id);
}
_ {
cx.ccx.sess.span_fatal(item.span,
"unbound function item in trans_item");
ccx.sess.span_fatal(item.span,
"unbound function item in trans_item");
}
}
}
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) {
trans_res_ctor(cx, decl, ctor_id, tps);
trans_res_ctor(ccx, *path, decl, ctor_id, tps);
// Create a function for the destructor
alt cx.ccx.item_ids.find(item.id) {
alt ccx.item_ids.find(item.id) {
some(lldtor_decl) {
trans_fn(cx, decl, body, lldtor_decl, no_self,
tps, dtor_id);
trans_fn(ccx, *path + [path_name(item.ident)], decl, body,
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) {
let sub_cx =
@{path: cx.path + [item.ident],
module_path: cx.module_path + [item.ident] with *cx};
trans_mod(sub_cx, m);
trans_mod(ccx, m);
}
ast::item_enum(variants, tps) {
let sub_cx = extend_path(cx, item.ident);
let degen = vec::len(variants) == 1u;
let vi = ty::enum_variants(cx.ccx.tcx, {crate: ast::local_crate,
node: item.id});
let vi = ty::enum_variants(ccx.tcx, local_def(item.id));
let i = 0;
for variant: ast::variant in variants {
trans_enum_variant(sub_cx, item.id, variant,
vi[i].disr_val, degen, tps);
trans_enum_variant(ccx, item.id, variant,
vi[i].disr_val, degen, tps);
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) {
let abi = alt attr::native_abi(item.attrs) {
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 */ }
}
@ -4991,8 +4959,8 @@ fn trans_item(cx: @local_ctxt, item: ast::item) {
// separate modules in the compiled program. That's because modules exist
// only as a convenience for humans working with the code, to organize names
// and control visibility.
fn trans_mod(cx: @local_ctxt, m: ast::_mod) {
for item: @ast::item in m.items { trans_item(cx, *item); }
fn trans_mod(ccx: @crate_ctxt, m: ast::_mod) {
for item in m.items { trans_item(ccx, *item); }
}
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);
}
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) {
// FIXME: pull this out
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)
}
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,
node_type: ty::t)
: returns_non_ty_var(ccx, node_type) {
let path = path;
let llfty = type_of_fn_from_ty(ccx, node_type,
vec::map(tps, {|p| param_bounds(ccx, p)}));
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_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); }
}
@ -5061,7 +5028,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
let llfdecl = decl_fn(ccx.llmod, "_rust_main",
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 lltop = bcx.llbb;
@ -5115,9 +5082,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
// on the stack).
fn create_real_fn_pair(cx: @block_ctxt, llfnty: TypeRef, llfn: ValueRef,
llenvptr: ValueRef) -> ValueRef {
let lcx = cx.fcx.lcx;
let pair = alloca(cx, T_fn_pair(lcx.ccx, llfnty));
let pair = alloca(cx, T_fn_pair(bcx_ccx(cx), llfnty));
fill_fn_pair(cx, pair, llfn, llenvptr);
ret pair;
}
@ -5137,9 +5102,10 @@ fn native_fn_ty_param_count(cx: @crate_ctxt, id: ast::node_id) -> uint {
let count;
let native_item =
// invariant?!
alt cx.ast_map.find(id) { some(ast_map::node_native_item(i)) { i }
_ { cx.sess.bug("native_fn_ty_param_count\
given a non-native item"); } };
alt cx.ast_map.find(id) {
some(ast_map::node_native_item(i, _)) { i }
_ { cx.sess.bug("native_fn_ty_param_count \
given a non-native item"); } };
alt native_item.node {
ast::native_item_fn(_, tps) {
count = vec::len::<ast::ty_param>(tps);
@ -5177,9 +5143,7 @@ fn link_name(i: @ast::native_item) -> str {
fn collect_native_item(ccx: @crate_ctxt,
abi: @mutable option<ast::native_abi>,
i: @ast::native_item,
&&pt: [str],
_v: vt<[str]>) {
i: @ast::native_item) {
alt i.node {
ast::native_item_fn(_, tps) {
let id = i.id;
@ -5217,8 +5181,10 @@ fn collect_native_item(ccx: @crate_ctxt,
// For true external functions: create a rust wrapper
// and link to that. The rust wrapper will handle
// switching to the C stack.
let new_pt = pt + [i.ident];
register_fn(ccx, i.span, new_pt, "native fn", tps, i.id);
let path = *alt ccx.tcx.items.get(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,15 +5192,20 @@ 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>,
i: @ast::item, &&pt: [str], v: vt<[str]>) {
let new_pt = pt + [i.ident];
i: @ast::item) {
let my_path = item_path(ccx, i);
alt i.node {
ast::item_const(_, _) {
let typ = node_id_type(ccx, i.id);
let s =
mangle_exported_name(ccx, pt + [i.ident],
node_id_type(ccx, i.id));
let s = mangle_exported_name(ccx, my_path,
node_id_type(ccx, i.id));
// FIXME: Could follow from a constraint on types of const
// items
let g = str::as_buf(s, {|buf|
@ -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(),
alt attr::native_abi(i.attrs) {
either::left(msg) { ccx.sess.span_fatal(i.span, msg); }
either::right(abi_) {
*abi = option::some(abi_);
}
either::right(abi_) { *abi = option::some(abi_); }
}
}
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) {
let name = i.ident + int::str(i.id);
let path = my_path + [path_name(int::str(i.id))];
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);
}
}
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
// the dtor_id. This is a bit counter-intuitive, but simplifies
// 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);
// FIXME: how to get rid of this check?
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) {
for variant in variants {
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);
}
}
}
_ { }
}
visit::visit_item(i, new_pt, v);
}
fn collect_items(ccx: @crate_ctxt, crate: @ast::crate) {
let abi = @mutable none::<ast::native_abi>;
visit::visit_crate(*crate, [], visit::mk_vt(@{
visit_native_item: bind collect_native_item(ccx, abi, _, _, _),
visit_item: bind collect_item(ccx, abi, _, _, _)
with *visit::default_visitor()
visit::visit_crate(*crate, (), visit::mk_simple_visitor(@{
visit_native_item: bind collect_native_item(ccx, abi, _),
visit_item: bind collect_item(ccx, abi, _)
with *visit::default_simple_visitor()
}));
}
// The constant translation pass.
fn trans_constant(ccx: @crate_ctxt, it: @ast::item, &&pt: [str],
v: vt<[str]>) {
let new_pt = pt + [it.ident];
visit::visit_item(it, new_pt, v);
fn trans_constant(ccx: @crate_ctxt, it: @ast::item) {
alt it.node {
ast::item_enum(variants, _) {
let vi = ty::enum_variants(ccx.tcx, {crate: ast::local_crate,
node: it.id});
let i = 0;
node: it.id});
let i = 0, path = item_path(ccx, it);
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 disr_val = vi[i].disr_val;
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::LLVMSetGlobalConstant(discrim_gvar, True);
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);
i += 1;
}
}
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));
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(_, _) {
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) {
let visitor =
@{visit_item: bind trans_constant(ccx, _, _, _)
with *visit::default_visitor()};
visit::visit_crate(*crate, [], visit::mk_vt(visitor));
visit::visit_crate(*crate, (), visit::mk_simple_visitor(@{
visit_item: bind trans_constant(ccx, _)
with *visit::default_simple_visitor()
}));
}
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,
dbg_cx: dbg_cx,
mutable do_not_commit_warning_issued: false};
let cx = new_local_ctxt(ccx);
collect_items(ccx, crate);
trans_constants(ccx, crate);
trans_mod(cx, crate.node.module);
trans_mod(ccx, crate.node.module);
fill_crate_map(ccx, crate_map);
emit_tydescs(ccx);
shape::gen_shape_tables(ccx);
write_abi_version(ccx);
// Translate the metadata.
write_metadata(cx.ccx, crate);
write_metadata(ccx, crate);
if ccx.sess.opts.stats {
#error("--- trans stats ---");
#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};
fn B(cx: @block_ctxt) -> BuilderRef {
let b = *cx.fcx.lcx.ccx.builder;
let b = *cx.fcx.ccx.builder;
llvm::LLVMPositionBuilderAtEnd(b, cx.llbb);
ret b;
}
@ -312,7 +312,7 @@ fn Free(cx: @block_ctxt, PointerVal: ValueRef) {
}
fn Load(cx: @block_ctxt, PointerVal: ValueRef) -> ValueRef {
let ccx = cx.fcx.lcx.ccx;
let ccx = cx.fcx.ccx;
if cx.unreachable {
let ty = val_ty(PointerVal);
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 {
let ccx = cx.fcx.lcx.ccx;
let ccx = cx.fcx.ccx;
let ty = val_ty(Fn);
let retty = if llvm::LLVMGetTypeKind(ty) == 8 as c_int {
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 {
let ccx = cx.fcx.lcx.ccx;
let ccx = cx.fcx.ccx;
if cx.unreachable { ret llvm::LLVMGetUndef(ccx.int_type); }
ret llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname());
}

View File

@ -16,6 +16,7 @@ import back::link::{
mangle_internal_name_by_path_and_seq};
import util::ppaux::ty_to_str;
import shape::{size_of};
import ast_map::{path, path_mod, path_name};
// ___Good to know (tm)__________________________________________________
//
@ -458,16 +459,16 @@ fn trans_expr_fn(bcx: @block_ctxt,
let ccx = bcx_ccx(bcx), bcx = bcx;
let fty = node_id_type(ccx, id);
let llfnty = type_of_fn_from_ty(ccx, fty, []);
let sub_cx = extend_path(bcx.fcx.lcx, ccx.names("anon"));
let s = mangle_internal_name_by_path(ccx, sub_cx.path);
let sub_path = bcx.fcx.path + [path_name("anon")];
let s = mangle_internal_name_by_path(ccx, sub_path);
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 cap_vars = capture::compute_capture_vars(
ccx.tcx, id, proto, cap_clause);
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);
});
llbox
@ -479,7 +480,8 @@ fn trans_expr_fn(bcx: @block_ctxt,
ast::proto_uniq { trans_closure_env(ty::ck_uniq) }
ast::proto_bare {
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
}
};
@ -569,9 +571,9 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
ty::ck_box);
// Make thunk
let llthunk =
trans_bind_thunk(cx.fcx.lcx, pair_ty, outgoing_fty_real, args,
cdata_ty, *param_bounds, target_res);
let llthunk = trans_bind_thunk(
cx.fcx.ccx, cx.fcx.path, pair_ty, outgoing_fty_real, args,
cdata_ty, *param_bounds, target_res);
// Fill the function pair
fill_fn_pair(bcx, get_dest_addr(dest), llthunk.val, llbox);
@ -727,7 +729,8 @@ fn make_opaque_cbox_free_glue(
}
// pth is cx.path
fn trans_bind_thunk(cx: @local_ctxt,
fn trans_bind_thunk(ccx: @crate_ctxt,
path: path,
incoming_fty: ty::t,
outgoing_fty: ty::t,
args: [option<@ast::expr>],
@ -743,8 +746,7 @@ fn trans_bind_thunk(cx: @local_ctxt,
type_has_static_size(ccx, incoming_fty) ->
*/
// but since we don't, we have to do the checks at the beginning.
let ccx = cx.ccx;
let tcx = ccx_tcx(ccx);
let tcx = ccx.tcx;
check type_has_static_size(ccx, incoming_fty);
#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.
// Give the thunk a name, type, and value.
let s: str = mangle_internal_name_by_path_and_seq(ccx, cx.path, "thunk");
let llthunk_ty: TypeRef = get_pair_fn_ty(type_of(ccx, incoming_fty));
let llthunk: ValueRef = decl_internal_cdecl_fn(ccx.llmod, s, llthunk_ty);
let s = mangle_internal_name_by_path_and_seq(ccx, path, "thunk");
let llthunk_ty = get_pair_fn_ty(type_of(ccx, incoming_fty));
let llthunk = decl_internal_cdecl_fn(ccx.llmod, s, llthunk_ty);
// 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.
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 lltop = bcx.llbb;
// 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
// 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.
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
// to be the correct type. Cast it to f's return type, if necessary.
let llretptr = fcx.llretptr;
let ccx = cx.ccx;
if ty::type_contains_params(ccx.tcx, outgoing_ret_ty) {
check non_ty_var(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 outgoing_arg_index: uint = 0u;
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 {
let out_arg = outgoing_args[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
// 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);
}
llargs += [val];
@ -913,7 +914,7 @@ fn trans_bind_thunk(cx: @local_ctxt,
// Arg will be provided when the thunk is invoked.
none {
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);
}
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
// in the closure does not know how many type descriptors the function
// needs to take.
let ccx = bcx_ccx(bcx);
let lltargetty =
type_of_fn_from_ty(ccx, outgoing_fty, param_bounds);
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};
import lib::llvm::{ModuleRef, ValueRef, TypeRef, BasicBlockRef, BuilderRef};
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.
import base::{type_of_fn, drop_ty};
@ -124,11 +125,6 @@ type crate_ctxt =
dbg_cx: option<@debuginfo::debug_ctxt>,
mutable do_not_commit_warning_issued: bool};
type local_ctxt =
{path: [str],
module_path: [str],
ccx: @crate_ctxt};
// Types used for llself.
type val_self_pair = {v: ValueRef, t: ty::t};
@ -239,9 +235,9 @@ type fn_ctxt =
mutable lltyparams: [fn_ty_param],
derived_tydescs: hashmap<ty::t, derived_tydesc_info>,
id: ast::node_id,
ret_style: ast::ret_style,
span: option<span>,
lcx: @local_ctxt};
path: path,
ccx: @crate_ctxt};
fn warn_not_to_commit(ccx: @crate_ctxt, msg: str) {
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_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 {
{bcx: bcx, val: val}
}
@ -430,13 +422,11 @@ fn find_scope_cx(cx: @block_ctxt) -> @block_ctxt {
// Accessors
// 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_ccx(bcx: @block_ctxt) -> @crate_ctxt { ret bcx.fcx.lcx.ccx; }
pure fn bcx_lcx(bcx: @block_ctxt) -> @local_ctxt { ret bcx.fcx.lcx; }
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.ccx; }
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_tcx(fcx: @fn_ctxt) -> ty::ctxt { ret fcx.lcx.ccx.tcx; }
pure fn lcx_ccx(lcx: @local_ctxt) -> @crate_ctxt { ret 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.ccx.tcx; }
pure fn ccx_tcx(ccx: @crate_ctxt) -> ty::ctxt { ret ccx.tcx; }
// 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));
}
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:
// mode: rust

View File

@ -10,6 +10,7 @@ import back::{link, abi};
import lib::llvm::llvm;
import lib::llvm::{ValueRef, TypeRef};
import lib::llvm::llvm::LLVMGetParam;
import ast_map::{path, path_mod, path_name};
// 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
// are referenced (ccx.method_map and ccx.dict_map).
fn trans_impl(cx: @local_ctxt, name: ast::ident, methods: [@ast::method],
id: ast::node_id, tps: [ast::ty_param]) {
let sub_cx = extend_path(cx, name);
fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
methods: [@ast::method], id: ast::node_id,
tps: [ast::ty_param]) {
let sub_path = path + [path_name(name)];
for m in methods {
alt cx.ccx.item_ids.find(m.id) {
alt ccx.item_ids.find(m.id) {
some(llfn) {
trans_fn(extend_path(sub_cx, m.ident), m.decl, m.body,
llfn, impl_self(ty::node_id_to_type(cx.ccx.tcx, id)),
trans_fn(ccx, sub_path + [path_name(m.ident)], m.decl, m.body,
llfn, impl_self(ty::node_id_to_type(ccx.tcx, 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);
}
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)
-> ValueRef {
let lcx = @{path: pt, module_path: [], ccx: ccx};
let name = link::mangle_internal_name_by_path(ccx, pt);
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 = fill(llfn, bcx);
build_return(bcx);
@ -194,7 +195,7 @@ fn trans_wrapper(ccx: @crate_ctxt, pt: [ast::ident], llfty: TypeRef,
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)
-> ValueRef {
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],
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 ptrs = vec::map(*ty::iface_methods(ccx.tcx, iface_id), {|im|
alt vec::find(ms, {|m| m.ident == im.ident}) {
some(m) {
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 \
@ -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);
}
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 {
let {llty: llfty, _} = wrapper_fn_ty(ccx, T_ptr(T_i8()), m);
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) {
let new_pt = pt + [it.ident + int::str(it.id)];
fn trans_iface_vtable(ccx: @crate_ctxt, pt: path, it: @ast::item) {
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 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;
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);
}

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
// moved there to avoid having to call eval_const_expr twice.
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;
@vec::map(variants, {|variant|
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) }
else {
alt tcx.items.find(id.node) {
some(ast_map::node_item(item)) {
some(ast_map::node_item(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)
}
_ {
@ -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 {
alt tcx.items.get(did.node) {
ast_map::node_item(@{node: ast::item_impl(ts, _, st, _),
_}) {
_}, _) {
{n_tps: vec::len(ts), ty: ast_ty_to_ty(tcx, m_check, st)}
}
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 {
if did.crate == ast::local_crate {
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);
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; } }
}
fn is_main_name(path: [ast::ident]) -> bool {
str::eq(option::get(vec::last(path)), "main")
fn is_main_name(path: middle::ast_map::path) -> bool {
option::get(vec::last(path)) == middle::ast_map::path_name("main")
}
//
// Local Variables:
// mode: rust

View File

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

View File

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