trans: use DefKey directly in debuginfo for paths.
This commit is contained in:
parent
e945b2852e
commit
4e6b178649
@ -1400,15 +1400,11 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
|
||||
pub fn new(ccx: &'blk CrateContext<'blk, 'tcx>,
|
||||
llfndecl: ValueRef,
|
||||
fn_ty: FnType,
|
||||
definition: Option<(Instance<'tcx>,
|
||||
&ty::FnSig<'tcx>,
|
||||
Abi,
|
||||
&ty::Generics<'tcx>,
|
||||
Option<ast::Name>)>,
|
||||
definition: Option<(Instance<'tcx>, &ty::FnSig<'tcx>, Abi)>,
|
||||
block_arena: &'blk TypedArena<common::BlockS<'blk, 'tcx>>)
|
||||
-> FunctionContext<'blk, 'tcx> {
|
||||
let (param_substs, def_id) = match definition {
|
||||
Some((instance, _, _, _, _)) => {
|
||||
Some((instance, _, _)) => {
|
||||
common::validate_substs(instance.substs);
|
||||
(instance.substs, Some(instance.def))
|
||||
}
|
||||
@ -1450,14 +1446,9 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
|
||||
None
|
||||
};
|
||||
|
||||
let span = inlined_id.and_then(|id| ccx.tcx().map.opt_span(id));
|
||||
|
||||
let debug_context = if let (false, Some(definition)) = (no_debug, definition) {
|
||||
let (instance, sig, abi, generics, name) = definition;
|
||||
debuginfo::create_function_debug_context(ccx, instance, sig,
|
||||
abi, generics, name,
|
||||
span.unwrap_or(DUMMY_SP),
|
||||
llfndecl)
|
||||
let (instance, sig, abi) = definition;
|
||||
debuginfo::create_function_debug_context(ccx, instance, sig, abi, llfndecl)
|
||||
} else {
|
||||
debuginfo::empty_function_debug_context(ccx)
|
||||
};
|
||||
@ -1476,7 +1467,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
|
||||
lldropflag_hints: RefCell::new(DropFlagHintsMap::new()),
|
||||
fn_ty: fn_ty,
|
||||
param_substs: param_substs,
|
||||
span: span,
|
||||
span: inlined_id.and_then(|id| ccx.tcx().map.opt_span(id)),
|
||||
block_arena: block_arena,
|
||||
lpad_arena: TypedArena::new(),
|
||||
ccx: ccx,
|
||||
@ -1831,8 +1822,6 @@ pub fn trans_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
inlined_id: ast::NodeId,
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
abi: Abi,
|
||||
generics: &ty::Generics<'tcx>,
|
||||
name: Option<ast::Name>,
|
||||
closure_env: closure::ClosureEnv) {
|
||||
ccx.stats().n_closures.set(ccx.stats().n_closures.get() + 1);
|
||||
|
||||
@ -1849,8 +1838,7 @@ pub fn trans_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
let (arena, fcx): (TypedArena<_>, FunctionContext);
|
||||
arena = TypedArena::new();
|
||||
fcx = FunctionContext::new(ccx, llfndecl, fn_ty,
|
||||
Some((instance, sig, abi, generics, name)), &arena);
|
||||
fcx = FunctionContext::new(ccx, llfndecl, fn_ty, Some((instance, sig, abi)), &arena);
|
||||
|
||||
if fcx.mir.is_some() {
|
||||
return mir::trans_mir(&fcx);
|
||||
@ -1931,8 +1919,7 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
} else {
|
||||
ccx.tcx().map.local_def_id(id)
|
||||
};
|
||||
let scheme = ccx.tcx().lookup_item_type(def_id);
|
||||
let fn_ty = scheme.ty;
|
||||
let fn_ty = ccx.tcx().lookup_item_type(def_id).ty;
|
||||
let fn_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &fn_ty);
|
||||
let sig = ccx.tcx().erase_late_bound_regions(fn_ty.fn_sig());
|
||||
let sig = infer::normalize_associated_type(ccx.tcx(), &sig);
|
||||
@ -1945,8 +1932,6 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
id,
|
||||
&sig,
|
||||
abi,
|
||||
&scheme.generics,
|
||||
Some(ccx.tcx().item_name(def_id)),
|
||||
closure::ClosureEnv::NotClosure);
|
||||
}
|
||||
|
||||
|
@ -235,10 +235,6 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
|
||||
variadic: false
|
||||
};
|
||||
|
||||
// This is not quite right. It should actually inherit
|
||||
// the generics of the enclosing function.
|
||||
let generics = ty::Generics::empty();
|
||||
|
||||
trans_closure(ccx,
|
||||
decl,
|
||||
body,
|
||||
@ -247,8 +243,6 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
|
||||
id,
|
||||
&sig,
|
||||
Abi::RustCall,
|
||||
&generics,
|
||||
None,
|
||||
ClosureEnv::Closure(closure_def_id, id));
|
||||
|
||||
// Don't hoist this to the top of the function. It's perfectly legitimate
|
||||
|
@ -16,7 +16,7 @@ use self::EnumDiscriminantInfo::*;
|
||||
use super::utils::{debug_context, DIB, span_start, bytes_to_bits, size_and_align_of,
|
||||
get_namespace_and_span_for_item, create_DIArray,
|
||||
fn_should_be_ignored, is_node_local_to_unit};
|
||||
use super::namespace::namespace_for_item;
|
||||
use super::namespace::mangled_name_of_item;
|
||||
use super::type_names::{compute_debuginfo_type_name, push_debuginfo_type_name};
|
||||
use super::{declare_local, VariableKind, VariableAccess};
|
||||
|
||||
@ -68,8 +68,8 @@ pub const UNKNOWN_LINE_NUMBER: c_uint = 0;
|
||||
pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
|
||||
|
||||
// ptr::null() doesn't work :(
|
||||
const NO_FILE_METADATA: DIFile = (0 as DIFile);
|
||||
const NO_SCOPE_METADATA: DIScope = (0 as DIScope);
|
||||
pub const NO_FILE_METADATA: DIFile = (0 as DIFile);
|
||||
pub const NO_SCOPE_METADATA: DIScope = (0 as DIScope);
|
||||
|
||||
const FLAGS_NONE: c_uint = 0;
|
||||
|
||||
@ -1846,28 +1846,8 @@ pub fn create_global_var_metadata(cx: &CrateContext,
|
||||
return;
|
||||
}
|
||||
|
||||
let var_item = cx.tcx().map.get(node_id);
|
||||
|
||||
let (name, span) = match var_item {
|
||||
hir_map::NodeItem(item) => {
|
||||
match item.node {
|
||||
hir::ItemStatic(..) => (item.name, item.span),
|
||||
hir::ItemConst(..) => (item.name, item.span),
|
||||
_ => {
|
||||
span_bug!(item.span,
|
||||
"debuginfo::\
|
||||
create_global_var_metadata() -
|
||||
Captured var-id refers to \
|
||||
unexpected ast_item variant: {:?}",
|
||||
var_item)
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => bug!("debuginfo::create_global_var_metadata() \
|
||||
- Captured var-id refers to unexpected \
|
||||
hir_map variant: {:?}",
|
||||
var_item)
|
||||
};
|
||||
let node_def_id = cx.tcx().map.local_def_id(node_id);
|
||||
let (var_scope, span) = get_namespace_and_span_for_item(cx, node_def_id);
|
||||
|
||||
let (file_metadata, line_number) = if span != codemap::DUMMY_SP {
|
||||
let loc = span_start(cx, span);
|
||||
@ -1879,12 +1859,8 @@ pub fn create_global_var_metadata(cx: &CrateContext,
|
||||
let is_local_to_unit = is_node_local_to_unit(cx, node_id);
|
||||
let variable_type = cx.tcx().node_id_to_type(node_id);
|
||||
let type_metadata = type_metadata(cx, variable_type, span);
|
||||
let node_def_id = cx.tcx().map.local_def_id(node_id);
|
||||
let namespace_node = namespace_for_item(cx, node_def_id);
|
||||
let var_name = name.to_string();
|
||||
let linkage_name =
|
||||
namespace_node.mangled_name_of_contained_item(&var_name[..]);
|
||||
let var_scope = namespace_node.scope;
|
||||
let var_name = cx.tcx().item_name(node_def_id).to_string();
|
||||
let linkage_name = mangled_name_of_item(cx, node_def_id, "");
|
||||
|
||||
let var_name = CString::new(var_name).unwrap();
|
||||
let linkage_name = CString::new(linkage_name).unwrap();
|
||||
|
@ -14,8 +14,9 @@ mod doc;
|
||||
use self::VariableAccess::*;
|
||||
use self::VariableKind::*;
|
||||
|
||||
use self::utils::{DIB, span_start, create_DIArray, is_node_local_to_unit};
|
||||
use self::namespace::{namespace_for_item, NamespaceTreeNode};
|
||||
use self::utils::{DIB, span_start, create_DIArray, is_node_local_to_unit,
|
||||
get_namespace_and_span_for_item};
|
||||
use self::namespace::mangled_name_of_item;
|
||||
use self::type_names::compute_debuginfo_type_name;
|
||||
use self::metadata::{type_metadata, diverging_type_metadata};
|
||||
use self::metadata::{file_metadata, scope_metadata, TypeMap, compile_unit_metadata};
|
||||
@ -26,6 +27,7 @@ use llvm::{ModuleRef, ContextRef, ValueRef};
|
||||
use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArray,
|
||||
FlagPrototyped};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::map::DefPathData;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::hir;
|
||||
|
||||
@ -34,18 +36,16 @@ use common::{NodeIdAndSpan, CrateContext, FunctionContext, Block};
|
||||
use monomorphize::Instance;
|
||||
use rustc::ty::{self, Ty};
|
||||
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
|
||||
use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet};
|
||||
use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet};
|
||||
|
||||
use libc::c_uint;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::ffi::CString;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
|
||||
use syntax::codemap::{Span, Pos};
|
||||
use syntax::{ast, codemap};
|
||||
use syntax::attr::IntType;
|
||||
use syntax::parse::token;
|
||||
|
||||
pub mod gdb;
|
||||
mod utils;
|
||||
@ -80,7 +80,7 @@ pub struct CrateDebugContext<'tcx> {
|
||||
created_enum_disr_types: RefCell<FnvHashMap<(DefId, IntType), DIType>>,
|
||||
|
||||
type_map: RefCell<TypeMap<'tcx>>,
|
||||
namespace_map: RefCell<FnvHashMap<Vec<ast::Name>, Rc<NamespaceTreeNode>>>,
|
||||
namespace_map: RefCell<DefIdMap<DIScope>>,
|
||||
|
||||
// This collection is used to assert that composite types (structs, enums,
|
||||
// ...) have their members only set once:
|
||||
@ -100,7 +100,7 @@ impl<'tcx> CrateDebugContext<'tcx> {
|
||||
created_files: RefCell::new(FnvHashMap()),
|
||||
created_enum_disr_types: RefCell::new(FnvHashMap()),
|
||||
type_map: RefCell::new(TypeMap::new()),
|
||||
namespace_map: RefCell::new(FnvHashMap()),
|
||||
namespace_map: RefCell::new(DefIdMap()),
|
||||
composite_types_completed: RefCell::new(FnvHashSet()),
|
||||
};
|
||||
}
|
||||
@ -232,9 +232,6 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
abi: Abi,
|
||||
generics: &ty::Generics<'tcx>,
|
||||
name: Option<ast::Name>,
|
||||
span: Span,
|
||||
llfn: ValueRef) -> FunctionDebugContext {
|
||||
if cx.sess().opts.debuginfo == NoDebugInfo {
|
||||
return FunctionDebugContext::DebugInfoDisabled;
|
||||
@ -245,6 +242,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
source_loc::set_debug_location(cx, InternalDebugLocation::UnknownLocation);
|
||||
|
||||
// This can be the case for functions inlined from another crate
|
||||
let (containing_scope, span) = get_namespace_and_span_for_item(cx, instance.def);
|
||||
if span == codemap::DUMMY_SP {
|
||||
return FunctionDebugContext::FunctionWithoutDebugInfo;
|
||||
}
|
||||
@ -257,38 +255,34 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
|
||||
};
|
||||
|
||||
// Find the enclosing function, in case this is a closure.
|
||||
let mut fn_def_id = instance.def;
|
||||
let mut def_key = cx.tcx().def_key(fn_def_id);
|
||||
let mut name = def_key.disambiguated_data.data.to_string();
|
||||
let name_len = name.len();
|
||||
while def_key.disambiguated_data.data == DefPathData::ClosureExpr {
|
||||
fn_def_id.index = def_key.parent.expect("closure without a parent?");
|
||||
def_key = cx.tcx().def_key(fn_def_id);
|
||||
}
|
||||
|
||||
// Get_template_parameters() will append a `<...>` clause to the function
|
||||
// name if necessary.
|
||||
let mut function_name = name.map(|name| name.to_string()).unwrap_or_else(|| {
|
||||
// We do this only for closures atm.
|
||||
format!("fn{}", token::gensym("fn"))
|
||||
});
|
||||
let generics = cx.tcx().lookup_item_type(fn_def_id).generics;
|
||||
let template_parameters = get_template_parameters(cx,
|
||||
generics,
|
||||
&generics,
|
||||
instance.substs,
|
||||
file_metadata,
|
||||
&mut function_name);
|
||||
&mut name);
|
||||
|
||||
// There is no hir_map::Path for hir::ExprClosure-type functions. For now,
|
||||
// just don't put them into a namespace. In the future this could be improved
|
||||
// somehow (storing a path in the hir_map, or construct a path using the
|
||||
// enclosing function).
|
||||
let (linkage_name, containing_scope) = if name.is_some() {
|
||||
let namespace_node = namespace_for_item(cx, instance.def);
|
||||
let linkage_name = namespace_node.mangled_name_of_contained_item(
|
||||
&function_name[..]);
|
||||
let containing_scope = namespace_node.scope;
|
||||
(linkage_name, containing_scope)
|
||||
} else {
|
||||
(function_name.clone(), file_metadata)
|
||||
};
|
||||
// Build the linkage_name out of the item path and "template" parameters.
|
||||
let linkage_name = mangled_name_of_item(cx, instance.def, &name[name_len..]);
|
||||
|
||||
let scope_line = span_start(cx, span).line;
|
||||
|
||||
let local_id = cx.tcx().map.as_local_node_id(instance.def);
|
||||
let is_local_to_unit = local_id.map_or(false, |id| is_node_local_to_unit(cx, id));
|
||||
|
||||
let function_name = CString::new(function_name).unwrap();
|
||||
let function_name = CString::new(name).unwrap();
|
||||
let linkage_name = CString::new(linkage_name).unwrap();
|
||||
let fn_metadata = unsafe {
|
||||
llvm::LLVMDIBuilderCreateFunction(
|
||||
|
@ -10,118 +10,82 @@
|
||||
|
||||
// Namespace Handling.
|
||||
|
||||
use super::utils::{DIB, debug_context};
|
||||
use super::metadata::{file_metadata, NO_FILE_METADATA, UNKNOWN_LINE_NUMBER};
|
||||
use super::utils::{DIB, debug_context, span_start};
|
||||
|
||||
use llvm;
|
||||
use llvm::debuginfo::DIScope;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::hir::map::DefPathData;
|
||||
use common::CrateContext;
|
||||
|
||||
use libc::c_uint;
|
||||
use std::ffi::CString;
|
||||
use std::iter::once;
|
||||
use std::ptr;
|
||||
use std::rc::{Rc, Weak};
|
||||
use syntax::ast;
|
||||
use syntax::parse::token;
|
||||
use syntax::codemap::DUMMY_SP;
|
||||
|
||||
pub struct NamespaceTreeNode {
|
||||
pub name: ast::Name,
|
||||
pub scope: DIScope,
|
||||
pub parent: Option<Weak<NamespaceTreeNode>>,
|
||||
}
|
||||
|
||||
impl NamespaceTreeNode {
|
||||
pub fn mangled_name_of_contained_item(&self, item_name: &str) -> String {
|
||||
fn fill_nested(node: &NamespaceTreeNode, output: &mut String) {
|
||||
match node.parent {
|
||||
Some(ref parent) => fill_nested(&parent.upgrade().unwrap(), output),
|
||||
None => {}
|
||||
pub fn mangled_name_of_item(ccx: &CrateContext, def_id: DefId, extra: &str) -> String {
|
||||
fn fill_nested(ccx: &CrateContext, def_id: DefId, extra: &str, output: &mut String) {
|
||||
let def_key = ccx.tcx().def_key(def_id);
|
||||
if let Some(parent) = def_key.parent {
|
||||
fill_nested(ccx, DefId {
|
||||
krate: def_id.krate,
|
||||
index: parent
|
||||
}, "", output);
|
||||
}
|
||||
let string = node.name.as_str();
|
||||
output.push_str(&string.len().to_string());
|
||||
output.push_str(&string);
|
||||
|
||||
let name = match def_key.disambiguated_data.data {
|
||||
DefPathData::CrateRoot => ccx.tcx().crate_name(def_id.krate),
|
||||
data => data.as_interned_str()
|
||||
};
|
||||
|
||||
output.push_str(&(name.len() + extra.len()).to_string());
|
||||
output.push_str(&name);
|
||||
output.push_str(extra);
|
||||
}
|
||||
|
||||
let mut name = String::from("_ZN");
|
||||
fill_nested(self, &mut name);
|
||||
name.push_str(&item_name.len().to_string());
|
||||
name.push_str(item_name);
|
||||
fill_nested(ccx, def_id, extra, &mut name);
|
||||
name.push('E');
|
||||
name
|
||||
}
|
||||
}
|
||||
|
||||
pub fn namespace_for_item(cx: &CrateContext, def_id: DefId) -> Rc<NamespaceTreeNode> {
|
||||
// prepend crate name.
|
||||
// This shouldn't need a roundtrip through InternedString.
|
||||
let krate = token::intern(&cx.tcx().crate_name(def_id.krate));
|
||||
let krate = hir_map::DefPathData::TypeNs(krate);
|
||||
let path = cx.tcx().def_path(def_id).data;
|
||||
let mut path = once(krate).chain(path.into_iter().map(|e| e.data)).peekable();
|
||||
|
||||
let mut current_key = Vec::new();
|
||||
let mut parent_node: Option<Rc<NamespaceTreeNode>> = None;
|
||||
|
||||
// Create/Lookup namespace for each element of the path.
|
||||
loop {
|
||||
// Emulate a for loop so we can use peek below.
|
||||
let path_element = match path.next() {
|
||||
Some(e) => e,
|
||||
None => break
|
||||
};
|
||||
// Ignore the name of the item (the last path element).
|
||||
if path.peek().is_none() {
|
||||
break;
|
||||
pub fn item_namespace(ccx: &CrateContext, def_id: DefId) -> DIScope {
|
||||
if let Some(&scope) = debug_context(ccx).namespace_map.borrow().get(&def_id) {
|
||||
return scope;
|
||||
}
|
||||
|
||||
// This shouldn't need a roundtrip through InternedString.
|
||||
let namespace_name = path_element.as_interned_str();
|
||||
let name = token::intern(&namespace_name);
|
||||
current_key.push(name);
|
||||
|
||||
let existing_node = debug_context(cx).namespace_map.borrow()
|
||||
.get(¤t_key).cloned();
|
||||
let current_node = match existing_node {
|
||||
Some(existing_node) => existing_node,
|
||||
None => {
|
||||
// create and insert
|
||||
let parent_scope = match parent_node {
|
||||
Some(ref node) => node.scope,
|
||||
None => ptr::null_mut()
|
||||
};
|
||||
let namespace_name = CString::new(namespace_name.as_bytes()).unwrap();
|
||||
let scope = unsafe {
|
||||
llvm::LLVMDIBuilderCreateNameSpace(
|
||||
DIB(cx),
|
||||
parent_scope,
|
||||
namespace_name.as_ptr(),
|
||||
// cannot reconstruct file ...
|
||||
ptr::null_mut(),
|
||||
// ... or line information, but that's not so important.
|
||||
0)
|
||||
};
|
||||
|
||||
let node = Rc::new(NamespaceTreeNode {
|
||||
name: name,
|
||||
scope: scope,
|
||||
parent: parent_node.map(|parent| Rc::downgrade(&parent)),
|
||||
let def_key = ccx.tcx().def_key(def_id);
|
||||
let parent_scope = def_key.parent.map_or(ptr::null_mut(), |parent| {
|
||||
item_namespace(ccx, DefId {
|
||||
krate: def_id.krate,
|
||||
index: parent
|
||||
})
|
||||
});
|
||||
|
||||
debug_context(cx).namespace_map.borrow_mut()
|
||||
.insert(current_key.clone(), node.clone());
|
||||
|
||||
node
|
||||
}
|
||||
let namespace_name = match def_key.disambiguated_data.data {
|
||||
DefPathData::CrateRoot => ccx.tcx().crate_name(def_id.krate),
|
||||
data => data.as_interned_str()
|
||||
};
|
||||
|
||||
parent_node = Some(current_node);
|
||||
}
|
||||
let namespace_name = CString::new(namespace_name.as_bytes()).unwrap();
|
||||
let span = ccx.tcx().map.def_id_span(def_id, DUMMY_SP);
|
||||
let (file, line) = if span != DUMMY_SP {
|
||||
let loc = span_start(ccx, span);
|
||||
(file_metadata(ccx, &loc.file.name), loc.line as c_uint)
|
||||
} else {
|
||||
(NO_FILE_METADATA, UNKNOWN_LINE_NUMBER)
|
||||
};
|
||||
|
||||
match parent_node {
|
||||
Some(node) => node,
|
||||
None => {
|
||||
bug!("debuginfo::namespace_for_item: path too short for {:?}", def_id);
|
||||
}
|
||||
}
|
||||
let scope = unsafe {
|
||||
llvm::LLVMDIBuilderCreateNameSpace(
|
||||
DIB(ccx),
|
||||
parent_scope,
|
||||
namespace_name.as_ptr(),
|
||||
file,
|
||||
line as c_uint)
|
||||
};
|
||||
|
||||
debug_context(ccx).namespace_map.borrow_mut().insert(def_id, scope);
|
||||
scope
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
// Utility Functions.
|
||||
|
||||
use super::{FunctionDebugContext, CrateDebugContext};
|
||||
use super::namespace::namespace_for_item;
|
||||
use super::namespace::item_namespace;
|
||||
|
||||
use rustc::hir::def_id::DefId;
|
||||
|
||||
@ -79,10 +79,17 @@ pub fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
|
||||
|
||||
pub fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: DefId)
|
||||
-> (DIScope, Span) {
|
||||
let containing_scope = namespace_for_item(cx, def_id).scope;
|
||||
let definition_span = cx.tcx().map.def_id_span(def_id, codemap::DUMMY_SP /* (1) */ );
|
||||
let containing_scope = item_namespace(cx, DefId {
|
||||
krate: def_id.krate,
|
||||
index: cx.tcx().def_key(def_id).parent
|
||||
.expect("get_namespace_and_span_for_item: missing parent?")
|
||||
});
|
||||
|
||||
// (1) For external items there is no span information
|
||||
// Try to get some span information, if we have an inlined item.
|
||||
let definition_span = match cx.external().borrow().get(&def_id) {
|
||||
Some(&Some(node_id)) => cx.tcx().map.span(node_id),
|
||||
_ => cx.tcx().map.def_id_span(def_id, codemap::DUMMY_SP)
|
||||
};
|
||||
|
||||
(containing_scope, definition_span)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user