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;
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};
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)
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[..]);