Skip to content

Commit

Permalink
Properly create debug info for functions
Browse files Browse the repository at this point in the history
We're currently using the actual function type as the return type when
creating the debug info for a function, so we're actually creating
debug info for a function that takes the same parameters, and returns
the actual function type, which is completely wrong.
  • Loading branch information
dotdash committed Jul 18, 2015
1 parent 3f50dca commit 1373c4f
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/librustc_trans/trans/debuginfo/metadata.rs
Expand Up @@ -920,7 +920,7 @@ pub fn scope_metadata(fcx: &FunctionContext,
}
}

fn diverging_type_metadata(cx: &CrateContext) -> DIType {
pub fn diverging_type_metadata(cx: &CrateContext) -> DIType {
unsafe {
llvm::LLVMDIBuilderCreateBasicType(
DIB(cx),
Expand Down
51 changes: 29 additions & 22 deletions src/librustc_trans/trans/debuginfo/mod.rs
Expand Up @@ -18,7 +18,8 @@ use self::utils::{DIB, span_start, assert_type_for_node_id, contains_nodebug_att
create_DIArray, is_node_local_to_unit};
use self::namespace::{namespace_for_item, NamespaceTreeNode};
use self::type_names::compute_debuginfo_type_name;
use self::metadata::{type_metadata, file_metadata, scope_metadata, TypeMap, compile_unit_metadata};
use self::metadata::{type_metadata, diverging_type_metadata};
use self::metadata::{file_metadata, scope_metadata, TypeMap, compile_unit_metadata};
use self::source_loc::InternalDebugLocation;

use llvm;
Expand All @@ -30,7 +31,7 @@ use rustc::ast_map;
use trans::common::{NodeIdAndSpan, CrateContext, FunctionContext, Block};
use trans;
use trans::monomorphize;
use middle::ty::Ty;
use middle::ty::{self, Ty};
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet};

Expand Down Expand Up @@ -325,7 +326,6 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let function_type_metadata = unsafe {
let fn_signature = get_function_signature(cx,
fn_ast_id,
&*fn_decl,
param_substs,
span);
llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
Expand Down Expand Up @@ -402,35 +402,42 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,

fn get_function_signature<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
fn_ast_id: ast::NodeId,
fn_decl: &ast::FnDecl,
param_substs: &Substs<'tcx>,
error_reporting_span: Span) -> DIArray {
if cx.sess().opts.debuginfo == LimitedDebugInfo {
return create_DIArray(DIB(cx), &[]);
}

let mut signature = Vec::with_capacity(fn_decl.inputs.len() + 1);

// Return type -- llvm::DIBuilder wants this at index 0
assert_type_for_node_id(cx, fn_ast_id, error_reporting_span);
let return_type = cx.tcx().node_id_to_type(fn_ast_id);
let return_type = monomorphize::apply_param_substs(cx.tcx(),
param_substs,
&return_type);
if return_type.is_nil() {
signature.push(ptr::null_mut())
} else {
signature.push(type_metadata(cx, return_type, codemap::DUMMY_SP));
}
let fn_type = cx.tcx().node_id_to_type(fn_ast_id);

let sig = match fn_type.sty {
ty::TyBareFn(_, ref barefnty) => {
cx.tcx().erase_late_bound_regions(&barefnty.sig)
}
ty::TyClosure(def_id, substs) => {
cx.tcx().erase_late_bound_regions(&cx.tcx().closure_type(def_id, substs).sig)
}

_ => cx.sess().bug("get_function_metdata: Expected a function type!")
};
let sig = monomorphize::apply_param_substs(cx.tcx(), param_substs, &sig);

let mut signature = Vec::with_capacity(sig.inputs.len() + 1);

// Return type -- llvm::DIBuilder wants this at index 0
signature.push(match sig.output {
ty::FnConverging(ret_ty) => match ret_ty.sty {
ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(),
_ => type_metadata(cx, ret_ty, codemap::DUMMY_SP)
},
ty::FnDiverging => diverging_type_metadata(cx)
});

// Arguments types
for arg in &fn_decl.inputs {
assert_type_for_node_id(cx, arg.pat.id, arg.pat.span);
let arg_type = cx.tcx().node_id_to_type(arg.pat.id);
let arg_type = monomorphize::apply_param_substs(cx.tcx(),
param_substs,
&arg_type);
signature.push(type_metadata(cx, arg_type, codemap::DUMMY_SP));
for &argument_type in &sig.inputs {
signature.push(type_metadata(cx, argument_type, codemap::DUMMY_SP));
}

return create_DIArray(DIB(cx), &signature[..]);
Expand Down
2 changes: 1 addition & 1 deletion src/test/debuginfo/basic-types-metadata.rs
Expand Up @@ -43,7 +43,7 @@
// gdb-command:whatis f64
// gdb-check:type = f64
// gdb-command:info functions _yyy
// gdb-check:[...]![...]_yyy([...])([...]);
// gdb-check:[...]![...]_yyy([...]);
// gdb-command:continue

#![allow(unused_variables)]
Expand Down

0 comments on commit 1373c4f

Please sign in to comment.