]> git.lizzy.rs Git - rust.git/commitdiff
Properly create debug info for functions
authorBjörn Steinbrink <bsteinbr@gmail.com>
Mon, 13 Jul 2015 19:48:07 +0000 (21:48 +0200)
committerBjörn Steinbrink <bsteinbr@gmail.com>
Sat, 18 Jul 2015 10:43:37 +0000 (12:43 +0200)
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.

src/librustc_trans/trans/debuginfo/metadata.rs
src/librustc_trans/trans/debuginfo/mod.rs
src/test/debuginfo/basic-types-metadata.rs

index 599a255ef8b6cee31462774900a5783f93bc4819..d1f524038961316a66a69c4a5fe654a538c705fd 100644 (file)
@@ -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),
index a87352989173104c409f6a239b8bc7c354f62dd3..39def5ed48aee8cdbf6efbb0328d227baeb8b9c2 100644 (file)
@@ -18,7 +18,8 @@
                   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;
@@ -30,7 +31,7 @@
 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};
 
@@ -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)
@@ -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[..]);
index 0134a058c992bd717f3cfe80db21801879559bf2..57dabadfbd546c9e17ce491a4dd7b817b83c2a6e 100644 (file)
@@ -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)]