提交 55c938b2 编写于 作者: M Marijn Haverbeke

Only build debuginfo blocks for blocks that appear in the program text

I.e. a set of curly braces, not everything that creates a block
context in the trans pass.

Issue #1694
上级 0ec92a4c
......@@ -7,7 +7,7 @@
import trans::base;
import trans::build::B;
import middle::ty;
import syntax::{ast, codemap};
import syntax::{ast, codemap, ast_util};
import codemap::span;
import ast::ty;
import pat_util::*;
......@@ -224,8 +224,17 @@ fn line_from_span(cm: codemap::codemap, sp: span) -> uint {
codemap::lookup_char_pos(cm, sp.lo).line
}
fn create_block(cx: @block_ctxt, sp: span) -> @metadata<block_md> {
//let cache = get_cache(bcx_ccx(cx));
fn create_block(cx: @block_ctxt) -> @metadata<block_md> {
let cache = get_cache(bcx_ccx(cx));
let cx = cx;
while option::is_none(cx.block_span) {
alt cx.parent {
parent_none { fail "BAD"; /*break;*/ }
parent_some(b) { cx = b; }
}
}
let sp = option::get(cx.block_span);
let start = codemap::lookup_char_pos(bcx_ccx(cx).sess.codemap,
sp.lo);
let fname = start.filename;
......@@ -240,25 +249,25 @@ fn create_block(cx: @block_ctxt, sp: span) -> @metadata<block_md> {
}*/
let parent = alt cx.parent {
parent_none { create_function(cx.fcx, sp).node }
parent_some(bcx) { create_block(bcx, sp).node }
parent_none { create_function(cx.fcx).node }
parent_some(bcx) { create_block(bcx).node }
};
let file_node = create_file(bcx_ccx(cx), fname);
/*let unique_id = alt cache.find(LexicalBlockTag) {
let unique_id = alt cache.find(LexicalBlockTag) {
option::some(v) { vec::len(v) as int }
option::none { 0 }
};*/
};
let lldata = [lltag(tg),
parent,
lli32(start.line as int),
lli32(start.col as int),
file_node.node/*,
lli32(unique_id)*/
file_node.node,
lli32(unique_id)
];
let val = llmdnode(lldata);
let mdval = @{node: val, data: {start: start, end: end}};
//update_cache(cache, tg, block_metadata(mdval));
ret mdval;
let val = llmdnode(lldata);
let mdval = @{node: val, data: {start: start, end: end}};
//update_cache(cache, tg, block_metadata(mdval));
ret mdval;
}
fn size_and_align_of<T>() -> (int, int) {
......@@ -642,8 +651,8 @@ fn create_local_var(bcx: @block_ctxt, local: @ast::local)
let tymd = create_ty(cx, ty, local.node.ty);
let filemd = create_file(cx, loc.filename);
let context = alt bcx.parent {
parent_none { create_function(bcx.fcx, local.span).node }
parent_some(_) { create_block(bcx, local.span).node }
parent_none { create_function(bcx.fcx).node }
parent_some(_) { create_block(bcx).node }
};
let mdnode = create_var(tg, context, name, filemd.node,
loc.line as int, tymd.node);
......@@ -684,7 +693,7 @@ fn create_arg(bcx: @block_ctxt, arg: ast::arg, sp: span)
let ty = base::node_id_type(cx, arg.id);
let tymd = create_ty(cx, ty, arg.ty);
let filemd = create_file(cx, loc.filename);
let context = create_function(bcx.fcx, sp);
let context = create_function(bcx.fcx);
let mdnode = create_var(tg, context.node, arg.ident, filemd.node,
loc.line as int, tymd.node);
let mdval = @{node: mdnode, data: {id: arg.id}};
......@@ -704,7 +713,7 @@ fn update_source_pos(cx: @block_ctxt, s: span) {
ret;
}
let cm = bcx_ccx(cx).sess.codemap;
let blockmd = create_block(cx, s);
let blockmd = create_block(cx);
let loc = codemap::lookup_char_pos(cm, s.lo);
let scopedata = [lli32(loc.line as int),
lli32(loc.col as int),
......@@ -714,14 +723,15 @@ fn update_source_pos(cx: @block_ctxt, s: span) {
llvm::LLVMSetCurrentDebugLocation(trans::build::B(cx), dbgscope);
}
fn create_function(fcx: @fn_ctxt, sp: span) -> @metadata<subprogram_md> {
fn create_function(fcx: @fn_ctxt) -> @metadata<subprogram_md> {
let cx = fcx_ccx(fcx);
let dbg_cx = option::get(cx.dbg_cx);
#debug("~~");
log(debug, fcx.id);
//log(debug, codemap::span_to_str(sp, cx.sess.codemap));
let sp = option::get(fcx.span);
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) {
......@@ -754,12 +764,12 @@ fn create_function(fcx: @fn_ctxt, sp: span) -> @metadata<subprogram_md> {
log(debug, ident);
log(debug, id);
/*let cache = get_cache(cx);
let cache = get_cache(cx);
alt cached_metadata::<@metadata<subprogram_md>>(
cache, SubprogramTag, {|md| md.data.id == id}) {
option::some(md) { ret md; }
option::none {}
}*/
}
let path = str::connect(fcx.lcx.path + [ident], "::");
......@@ -805,6 +815,6 @@ fn create_function(fcx: @fn_ctxt, sp: span) -> @metadata<subprogram_md> {
let val = llmdnode(fn_metadata);
add_named_metadata(cx, "llvm.dbg.sp", val);
let mdval = @{node: val, data: {id: id}};
//update_cache(cache, SubprogramTag, subprogram_metadata(mdval));
update_cache(cache, SubprogramTag, subprogram_metadata(mdval));
ret mdval;
}
......@@ -6,7 +6,8 @@
import lib::llvm::llvm::{ValueRef, BasicBlockRef};
import pat_util::*;
import build::*;
import base::{new_sub_block_ctxt, new_scope_block_ctxt, load_if_immediate};
import base::{new_sub_block_ctxt, new_scope_block_ctxt,
new_real_block_ctxt, load_if_immediate};
import syntax::ast;
import syntax::ast_util;
import syntax::ast_util::{dummy_sp};
......@@ -651,7 +652,8 @@ fn trans_alt(cx: @block_ctxt, expr: @ast::expr, arms_: [ast::arm],
let arms = normalize_arms(bcx_tcx(cx), arms_);
for a: ast::arm in arms {
let body = new_scope_block_ctxt(er.bcx, "case_body");
let body = new_real_block_ctxt(er.bcx, "case_body",
a.body.span);
let id_map = pat_util::pat_id_map(bcx_tcx(cx), a.pats[0]);
bodies += [body];
for p: @ast::pat in a.pats {
......
......@@ -1122,7 +1122,7 @@ fn declare_generic_glue(cx: @local_ctxt, t: ty::t, llfnty: TypeRef, name: str)
fn make_generic_glue_inner(cx: @local_ctxt, t: ty::t,
llfn: ValueRef, helper: glue_helper,
ty_params: [uint]) -> ValueRef {
let fcx = new_fn_ctxt(cx, llfn);
let fcx = new_fn_ctxt(cx, llfn, none);
llvm::LLVMSetLinkage(llfn,
lib::llvm::LLVMInternalLinkage as llvm::Linkage);
cx.ccx.stats.n_glues_created += 1u;
......@@ -1151,7 +1151,7 @@ fn make_generic_glue_inner(cx: @local_ctxt, t: ty::t,
fcx.lltyparams = vec::map_mut(lltydescs, {|d| {desc: d, dicts: none}});
let bcx = new_top_block_ctxt(fcx);
let bcx = new_top_block_ctxt(fcx, none);
let lltop = bcx.llbb;
let llrawptr0 = llvm::LLVMGetParam(llfn, 3u as c_uint);
let llval0 = BitCast(bcx, llrawptr0, llty);
......@@ -2410,8 +2410,11 @@ fn trans_if(cx: @block_ctxt, cond: @ast::expr, thn: ast::blk,
let then_dest = dup_for_join(dest);
let else_dest = dup_for_join(dest);
let then_cx = new_scope_block_ctxt(bcx, "then");
let else_cx = new_scope_block_ctxt(bcx, "else");
let then_cx = new_real_block_ctxt(bcx, "then", thn.span);
let else_cx = new_real_block_ctxt(bcx, "else", alt els {
some(e) { e.span }
_ { ast_util::dummy_sp() }
});
CondBr(bcx, cond_val, then_cx.llbb, else_cx.llbb);
then_cx = trans_block_dps(then_cx, thn, then_dest);
// Calling trans_block directly instead of trans_expr
......@@ -2442,7 +2445,8 @@ fn inner(bcx: @block_ctxt, local: @ast::local, curr: ValueRef, t: ty::t,
let next_cx = new_sub_block_ctxt(bcx, "next");
let scope_cx =
new_loop_scope_block_ctxt(bcx, option::some(next_cx),
outer_next_cx, "for loop scope");
outer_next_cx, "for loop scope",
body.span);
Br(bcx, scope_cx.llbb);
let curr = PointerCast(bcx, curr, T_ptr(type_of_or_i8(bcx, t)));
let bcx = alt::bind_irrefutable_pat(scope_cx, local.node.pat,
......@@ -2471,7 +2475,7 @@ fn trans_while(cx: @block_ctxt, cond: @ast::expr, body: ast::blk)
let next_cx = new_sub_block_ctxt(cx, "while next");
let cond_cx =
new_loop_scope_block_ctxt(cx, option::none::<@block_ctxt>, next_cx,
"while cond");
"while cond", body.span);
let body_cx = new_scope_block_ctxt(cond_cx, "while loop body");
let body_end = trans_block(body_cx, body);
let cond_res = trans_temp_expr(cond_cx, cond);
......@@ -2487,7 +2491,7 @@ fn trans_do_while(cx: @block_ctxt, body: ast::blk, cond: @ast::expr) ->
let next_cx = new_sub_block_ctxt(cx, "next");
let body_cx =
new_loop_scope_block_ctxt(cx, option::none::<@block_ctxt>, next_cx,
"do-while loop body");
"do-while loop body", body.span);
let body_end = trans_block(body_cx, body);
let cond_cx = new_scope_block_ctxt(body_cx, "do-while cond");
Br(body_end, cond_cx.llbb);
......@@ -3479,7 +3483,8 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
ret alt::trans_alt(bcx, expr, arms, dest);
}
ast::expr_block(blk) {
let sub_cx = new_scope_block_ctxt(bcx, "block-expr body");
let sub_cx = new_real_block_ctxt(bcx, "block-expr body",
blk.span);
Br(bcx, sub_cx.llbb);
sub_cx = trans_block_dps(sub_cx, blk, dest);
let next_cx = new_sub_block_ctxt(bcx, "next");
......@@ -4022,7 +4027,7 @@ fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> @block_ctxt {
// You probably don't want to use this one. See the
// next three functions instead.
fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind,
name: str) -> @block_ctxt {
name: str, block_span: option::t<span>) -> @block_ctxt {
let s = "";
if cx.lcx.ccx.sess.opts.save_temps ||
cx.lcx.ccx.sess.opts.debuginfo {
......@@ -4037,7 +4042,8 @@ fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind,
kind: kind,
mutable cleanups: [],
mutable lpad_dirty: true,
mutable lpad: option::none,
mutable lpad: none,
block_span: block_span,
fcx: cx};
alt parent {
parent_some(cx) {
......@@ -4050,26 +4056,32 @@ fn new_block_ctxt(cx: @fn_ctxt, parent: block_parent, kind: block_kind,
// Use this when you're at the top block of a function or the like.
fn new_top_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt {
ret new_block_ctxt(fcx, parent_none, SCOPE_BLOCK, "function top level");
fn new_top_block_ctxt(fcx: @fn_ctxt, sp: option::t<span>) -> @block_ctxt {
ret new_block_ctxt(fcx, parent_none, SCOPE_BLOCK, "function top level",
sp);
}
// Use this when you're at a curly-brace or similar lexical scope.
fn new_scope_block_ctxt(bcx: @block_ctxt, n: str) -> @block_ctxt {
ret new_block_ctxt(bcx.fcx, parent_some(bcx), SCOPE_BLOCK, n);
ret new_block_ctxt(bcx.fcx, parent_some(bcx), SCOPE_BLOCK, n, none);
}
fn new_real_block_ctxt(bcx: @block_ctxt, n: str, sp: span) -> @block_ctxt {
ret new_block_ctxt(bcx.fcx, parent_some(bcx), SCOPE_BLOCK, n, some(sp));
}
fn new_loop_scope_block_ctxt(bcx: @block_ctxt, _cont: option::t<@block_ctxt>,
_break: @block_ctxt, n: str) -> @block_ctxt {
_break: @block_ctxt, n: str, sp: span)
-> @block_ctxt {
ret new_block_ctxt(bcx.fcx, parent_some(bcx),
LOOP_SCOPE_BLOCK(_cont, _break), n);
LOOP_SCOPE_BLOCK(_cont, _break), n, some(sp));
}
// Use this when you're making a general CFG BB within a scope.
fn new_sub_block_ctxt(bcx: @block_ctxt, n: str) -> @block_ctxt {
ret new_block_ctxt(bcx.fcx, parent_some(bcx), NON_SCOPE_BLOCK, n);
ret new_block_ctxt(bcx.fcx, parent_some(bcx), NON_SCOPE_BLOCK, n, none);
}
fn new_raw_block_ctxt(fcx: @fn_ctxt, llbb: BasicBlockRef) -> @block_ctxt {
......@@ -4080,7 +4092,8 @@ fn new_raw_block_ctxt(fcx: @fn_ctxt, llbb: BasicBlockRef) -> @block_ctxt {
kind: NON_SCOPE_BLOCK,
mutable cleanups: [],
mutable lpad_dirty: true,
mutable lpad: option::none,
mutable lpad: none,
block_span: none,
fcx: fcx};
}
......@@ -4146,7 +4159,8 @@ fn llstaticallocas_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt {
kind: SCOPE_BLOCK,
mutable cleanups: [],
mutable lpad_dirty: true,
mutable lpad: option::none,
mutable lpad: none,
block_span: none,
fcx: fcx};
}
......@@ -4158,7 +4172,8 @@ fn llderivedtydescs_block_ctxt(fcx: @fn_ctxt) -> @block_ctxt {
kind: SCOPE_BLOCK,
mutable cleanups: [],
mutable lpad_dirty: true,
mutable lpad: option::none,
mutable lpad: none,
block_span: none,
fcx: fcx};
}
......@@ -4290,8 +4305,8 @@ fn mk_standard_basic_blocks(llfn: ValueRef) ->
// - 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_ctxt {
id: ast::node_id, rstyle: ast::ret_style,
sp: option::t<span>) -> @fn_ctxt {
let llbbs = mk_standard_basic_blocks(llfndecl);
ret @{llfn: llfndecl,
llenv: llvm::LLVMGetParam(llfndecl, 1u as c_uint),
......@@ -4311,11 +4326,13 @@ fn new_fn_ctxt_w_id(cx: @local_ctxt, llfndecl: ValueRef,
derived_tydescs: ty::new_ty_hash(),
id: id,
ret_style: rstyle,
span: sp,
lcx: cx};
}
fn new_fn_ctxt(cx: @local_ctxt, llfndecl: ValueRef) -> @fn_ctxt {
ret new_fn_ctxt_w_id(cx, llfndecl, -1, ast::return_val);
fn new_fn_ctxt(cx: @local_ctxt, llfndecl: ValueRef, sp: option::t<span>)
-> @fn_ctxt {
ret new_fn_ctxt_w_id(cx, llfndecl, -1, ast::return_val, sp);
}
// NB: must keep 4 fns in sync:
......@@ -4430,19 +4447,19 @@ 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(cx: @local_ctxt, sp: span, 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);
let fcx = new_fn_ctxt_w_id(cx, llfndecl, id, decl.cf, some(sp));
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);
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);
......@@ -4478,10 +4495,10 @@ fn trans_fn(cx: @local_ctxt, sp: span, decl: ast::fn_decl, body: ast::blk,
let do_time = cx.ccx.sess.opts.stats;
let start = do_time ? time::get_time() : {sec: 0u32, usec: 0u32};
let fcx = option::none;
trans_closure(cx, decl, body, llfndecl, ty_self, ty_params, id,
trans_closure(cx, sp, decl, body, llfndecl, ty_self, ty_params, id,
{|new_fcx| fcx = option::some(new_fcx);});
if cx.ccx.sess.opts.extra_debuginfo {
debuginfo::create_function(option::get(fcx), sp);
debuginfo::create_function(option::get(fcx));
}
if do_time {
let end = time::get_time();
......@@ -4495,10 +4512,10 @@ fn trans_res_ctor(cx: @local_ctxt, dtor: ast::fn_decl,
// Create a function for the constructor
let llctor_decl = ccx.item_ids.get(ctor_id);
let fcx = new_fn_ctxt(cx, llctor_decl);
let fcx = new_fn_ctxt(cx, llctor_decl, none);
let ret_t = ty::ret_ty_of_fn(cx.ccx.tcx, ctor_id);
create_llargs_for_fn_args(fcx, no_self, dtor.inputs, ty_params);
let bcx = new_top_block_ctxt(fcx);
let bcx = new_top_block_ctxt(fcx, none);
let lltop = bcx.llbb;
let arg_t = arg_tys_of_fn(ccx, ctor_id)[0].ty;
let tup_t = ty::mk_tup(ccx.tcx, [ty::mk_int(ccx.tcx), arg_t]);
......@@ -4555,7 +4572,7 @@ fn trans_enum_variant(cx: @local_ctxt, enum_id: ast::node_id,
"unbound variant id in trans_enum_variant");
}
}
let fcx = new_fn_ctxt(cx, llfndecl);
let fcx = new_fn_ctxt(cx, llfndecl, none);
create_llargs_for_fn_args(fcx, no_self, fn_args, ty_params);
let ty_param_substs: [ty::t] = [];
i = 0u;
......@@ -4565,7 +4582,7 @@ fn trans_enum_variant(cx: @local_ctxt, enum_id: ast::node_id,
i += 1u;
}
let arg_tys = arg_tys_of_fn(ccx, variant.node.id);
let bcx = new_top_block_ctxt(fcx);
let bcx = new_top_block_ctxt(fcx, none);
let lltop = bcx.llbb;
bcx = copy_args_to_allocas(fcx, bcx, fn_args, arg_tys);
......@@ -4777,8 +4794,8 @@ fn build_shim_fn(lcx: @local_ctxt,
ccx.llmod, shim_name, tys.shim_fn_ty);
// Declare the body of the shim function:
let fcx = new_fn_ctxt(lcx, llshimfn);
let bcx = new_top_block_ctxt(fcx);
let fcx = new_fn_ctxt(lcx, llshimfn, none);
let bcx = new_top_block_ctxt(fcx, none);
let lltop = bcx.llbb;
let llargbundle = llvm::LLVMGetParam(llshimfn, 0 as c_uint);
let i = 0u, n = vec::len(tys.arg_tys);
......@@ -4814,8 +4831,8 @@ fn build_wrap_fn(lcx: @local_ctxt,
llshimfn: ValueRef,
llwrapfn: ValueRef) {
let ccx = lcx_ccx(lcx);
let fcx = new_fn_ctxt(lcx, llwrapfn);
let bcx = new_top_block_ctxt(fcx);
let fcx = new_fn_ctxt(lcx, llwrapfn, none);
let bcx = new_top_block_ctxt(fcx, none);
let lltop = bcx.llbb;
// Allocate the struct and write the arguments into it.
......@@ -5006,9 +5023,9 @@ fn create_main(ccx: @crate_ctxt, main_llfn: ValueRef,
let llfdecl = decl_fn(ccx.llmod, "_rust_main",
lib::llvm::LLVMCCallConv, llfty);
let fcx = new_fn_ctxt(new_local_ctxt(ccx), llfdecl);
let fcx = new_fn_ctxt(new_local_ctxt(ccx), llfdecl, none);
let bcx = new_top_block_ctxt(fcx);
let bcx = new_top_block_ctxt(fcx, none);
let lltop = bcx.llbb;
let lloutputarg = llvm::LLVMGetParam(llfdecl, 0 as c_uint);
......
......@@ -520,7 +520,7 @@ fn trans_expr_fn(bcx: @block_ctxt,
let cap_vars = capture::compute_capture_vars(
ccx.tcx, id, proto, cap_clause);
let {llbox, cbox_ty, bcx} = build_closure(bcx, cap_vars, ck);
trans_closure(sub_cx, decl, body, llfn, no_self, [], id, {|fcx|
trans_closure(sub_cx, sp, decl, body, llfn, no_self, [], id, {|fcx|
load_environment(bcx, fcx, cbox_ty, cap_vars, ck);
});
llbox
......@@ -532,7 +532,7 @@ 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_cbox_ptr(ccx));
trans_closure(sub_cx, decl, body, llfn, no_self, [],
trans_closure(sub_cx, sp, decl, body, llfn, no_self, [],
id, {|_fcx|});
closure
}
......@@ -825,8 +825,8 @@ fn trans_bind_thunk(cx: @local_ctxt,
// 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);
let bcx = new_top_block_ctxt(fcx);
let fcx = new_fn_ctxt(cx, 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
// our bound tydescs, we need to load tydescs out of the environment
......
......@@ -240,6 +240,7 @@ enum local_val { local_mem(ValueRef), local_imm(ValueRef), }
derived_tydescs: hashmap<ty::t, derived_tydesc_info>,
id: ast::node_id,
ret_style: ast::ret_style,
span: option::t<span>,
lcx: @local_ctxt};
enum cleanup {
......@@ -331,22 +332,14 @@ fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, inner_t: ty::t)
}
enum block_kind {
// A scope block is a basic block created by translating a block { ... }
// in the source language. Since these blocks create variable scope, any
// variables created in them that are still live at the end of the block
// must be dropped and cleaned up when the block ends.
// A scope at the end of which temporary values created inside of it are
// cleaned up. May correspond to an actual block in the language, but also
// to an implicit scope, for example, calls introduce an implicit scope in
// which the arguments are evaluated and cleaned up.
SCOPE_BLOCK,
// A basic block created from the body of a loop. Contains pointers to
// which block to jump to in the case of "continue" or "break", with the
// "continue" block optional, because "while" and "do while" don't support
// "continue" (TODO: is this intentional?)
// which block to jump to in the case of "continue" or "break".
LOOP_SCOPE_BLOCK(option::t<@block_ctxt>, @block_ctxt),
// A non-scope block is a basic block created as a translation artifact
// from translating code that expresses conditional logic rather than by
// explicit { ... } block structure in the source language. It's called a
......@@ -382,6 +375,7 @@ enum block_kind {
mutable cleanups: [cleanup],
mutable lpad_dirty: bool,
mutable lpad: option::t<BasicBlockRef>,
block_span: option::t<span>,
fcx: @fn_ctxt};
// FIXME: we should be able to use option::t<@block_parent> here but
......
......@@ -178,8 +178,8 @@ fn trans_wrapper(ccx: @crate_ctxt, pt: [ast::ident], llfty: TypeRef,
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);
let bcx = new_top_block_ctxt(fcx), lltop = bcx.llbb;
let fcx = new_fn_ctxt(lcx, llfn, none);
let bcx = new_top_block_ctxt(fcx, none), lltop = bcx.llbb;
let bcx = fill(llfn, bcx);
build_return(bcx);
finish_fn(fcx, lltop);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册