about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-07-20 15:04:15 +0000
committerbors <bors@rust-lang.org>2015-07-20 15:04:15 +0000
commit39d4faf989cea236e2e1669ab85d060d1c62cd85 (patch)
treeb09f28f9ef799f0f1378f3775446209519e7200d
parent4e51763e6428580f2b3275cd7076492376801a1e (diff)
parent3d65c7ff849bea9cd44fc652396d50486396f867 (diff)
downloadrust-39d4faf989cea236e2e1669ab85d060d1c62cd85.tar.gz
rust-39d4faf989cea236e2e1669ab85d060d1c62cd85.zip
Auto merge of #27025 - dotdash:issue-26484, r=pnkfelix
See the commits for details

r? @arielb1 
-rw-r--r--src/librustc_trans/trans/debuginfo/metadata.rs27
-rw-r--r--src/librustc_trans/trans/debuginfo/mod.rs60
-rw-r--r--src/test/debuginfo/basic-types-metadata.rs5
-rw-r--r--src/test/run-pass/issue-26484.rs20
4 files changed, 84 insertions, 28 deletions
diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs
index 599a255ef8b..5f17197a4b9 100644
--- a/src/librustc_trans/trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/trans/debuginfo/metadata.rs
@@ -796,12 +796,31 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             }
         }
         ty::TyBareFn(_, ref barefnty) => {
-            subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
+            let fn_metadata = subroutine_type_metadata(cx,
+                                                       unique_type_id,
+                                                       &barefnty.sig,
+                                                       usage_site_span).metadata;
+            match debug_context(cx).type_map
+                                   .borrow()
+                                   .find_metadata_for_unique_id(unique_type_id) {
+                Some(metadata) => return metadata,
+                None => { /* proceed normally */ }
+            };
+
+            // This is actually a function pointer, so wrap it in pointer DI
+            MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false)
+
         }
         ty::TyClosure(def_id, substs) => {
             let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
-            let sig = infcx.closure_type(def_id, substs).sig;
-            subroutine_type_metadata(cx, unique_type_id, &sig, usage_site_span)
+            let upvars = infcx.closure_upvars(def_id, substs).unwrap();
+            let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
+
+            prepare_tuple_metadata(cx,
+                                   t,
+                                   &upvar_types[..],
+                                   unique_type_id,
+                                   usage_site_span).finalize(cx)
         }
         ty::TyStruct(def_id, substs) => {
             prepare_struct_metadata(cx,
@@ -920,7 +939,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),
diff --git a/src/librustc_trans/trans/debuginfo/mod.rs b/src/librustc_trans/trans/debuginfo/mod.rs
index a8735298917..9ce5c457bff 100644
--- a/src/librustc_trans/trans/debuginfo/mod.rs
+++ b/src/librustc_trans/trans/debuginfo/mod.rs
@@ -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;
@@ -29,8 +30,8 @@ use middle::subst::{self, Substs};
 use rustc::ast_map;
 use trans::common::{NodeIdAndSpan, CrateContext, FunctionContext, Block};
 use trans;
-use trans::monomorphize;
-use middle::ty::Ty;
+use trans::{monomorphize, type_of};
+use middle::ty::{self, Ty};
 use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
 use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet};
 
@@ -40,7 +41,7 @@ use std::ffi::CString;
 use std::ptr;
 use std::rc::Rc;
 use syntax::codemap::{Span, Pos};
-use syntax::{ast, codemap, ast_util};
+use syntax::{abi, ast, codemap, ast_util};
 use syntax::attr::IntType;
 use syntax::parse::token::{self, special_idents};
 
@@ -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,49 @@ 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())
+        let fn_type = cx.tcx().node_id_to_type(fn_ast_id);
+
+        let (sig, abi) = match fn_type.sty {
+            ty::TyBareFn(_, ref barefnty) => {
+                (cx.tcx().erase_late_bound_regions(&barefnty.sig), barefnty.abi)
+            }
+            ty::TyClosure(def_id, substs) => {
+                let closure_type = cx.tcx().closure_type(def_id, substs);
+                (cx.tcx().erase_late_bound_regions(&closure_type.sig), closure_type.abi)
+            }
+
+            _ => 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)
+        });
+
+        let inputs = &if abi == abi::RustCall {
+            type_of::untuple_arguments(cx, &sig.inputs)
         } else {
-            signature.push(type_metadata(cx, return_type, codemap::DUMMY_SP));
-        }
+            sig.inputs
+        };
 
         // 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 inputs {
+            signature.push(type_metadata(cx, argument_type, codemap::DUMMY_SP));
         }
 
         return create_DIArray(DIB(cx), &signature[..]);
diff --git a/src/test/debuginfo/basic-types-metadata.rs b/src/test/debuginfo/basic-types-metadata.rs
index 0134a058c99..2468150a6a5 100644
--- a/src/test/debuginfo/basic-types-metadata.rs
+++ b/src/test/debuginfo/basic-types-metadata.rs
@@ -42,8 +42,10 @@
 // gdb-check:type = f32
 // gdb-command:whatis f64
 // gdb-check:type = f64
+// gdb-command:whatis fnptr
+// gdb-check:type = [...] (*)([...])
 // gdb-command:info functions _yyy
-// gdb-check:[...]![...]_yyy([...])([...]);
+// gdb-check:[...]![...]_yyy([...]);
 // gdb-command:continue
 
 #![allow(unused_variables)]
@@ -65,6 +67,7 @@ fn main() {
     let u64: u64 = 64;
     let f32: f32 = 2.5;
     let f64: f64 = 3.5;
+    let fnptr : fn() = _zzz;
     _zzz(); // #break
     if 1 == 1 { _yyy(); }
 }
diff --git a/src/test/run-pass/issue-26484.rs b/src/test/run-pass/issue-26484.rs
new file mode 100644
index 00000000000..d3e6fc85f13
--- /dev/null
+++ b/src/test/run-pass/issue-26484.rs
@@ -0,0 +1,20 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags:-g
+
+fn helper<F: FnOnce(usize) -> bool>(_f: F) {
+    print!("");
+}
+
+fn main() {
+    let cond = 0;
+    helper(|v| v == cond)
+}