]>
git.proxmox.com Git - rustc.git/blob - src/librustc_trans/trans/debuginfo/namespace.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // Namespace Handling.
13 use super::utils
::{DIB, debug_context}
;
16 use llvm
::debuginfo
::DIScope
;
17 use trans
::common
::CrateContext
;
18 use middle
::ty
::{self, ClosureTyper}
;
20 use std
::ffi
::CString
;
22 use std
::rc
::{Rc, Weak}
;
23 use syntax
::{ast, ast_map}
;
24 use syntax
::parse
::token
;
26 pub struct NamespaceTreeNode
{
29 pub parent
: Option
<Weak
<NamespaceTreeNode
>>,
32 impl NamespaceTreeNode
{
33 pub fn mangled_name_of_contained_item(&self, item_name
: &str) -> String
{
34 fn fill_nested(node
: &NamespaceTreeNode
, output
: &mut String
) {
36 Some(ref parent
) => fill_nested(&*parent
.upgrade().unwrap(), output
),
39 let string
= token
::get_name(node
.name
);
40 output
.push_str(&format
!("{}", string
.len()));
41 output
.push_str(&string
);
44 let mut name
= String
::from_str("_ZN");
45 fill_nested(self, &mut name
);
46 name
.push_str(&format
!("{}", item_name
.len()));
47 name
.push_str(item_name
);
53 pub fn crate_root_namespace
<'a
>(cx
: &'a CrateContext
) -> &'a
str {
54 &cx
.link_meta().crate_name
57 pub fn namespace_for_item(cx
: &CrateContext
, def_id
: ast
::DefId
) -> Rc
<NamespaceTreeNode
> {
58 ty
::with_path(cx
.tcx(), def_id
, |path
| {
59 // prepend crate name if not already present
60 let krate
= if def_id
.krate
== ast
::LOCAL_CRATE
{
61 let crate_namespace_name
= token
::intern(crate_root_namespace(cx
));
62 Some(ast_map
::PathMod(crate_namespace_name
))
66 let mut path
= krate
.into_iter().chain(path
).peekable();
68 let mut current_key
= Vec
::new();
69 let mut parent_node
: Option
<Rc
<NamespaceTreeNode
>> = None
;
71 // Create/Lookup namespace for each element of the path.
73 // Emulate a for loop so we can use peek below.
74 let path_element
= match path
.next() {
78 // Ignore the name of the item (the last path element).
79 if path
.peek().is_none() {
83 let name
= path_element
.name();
84 current_key
.push(name
);
86 let existing_node
= debug_context(cx
).namespace_map
.borrow()
87 .get(¤t_key
).cloned();
88 let current_node
= match existing_node
{
89 Some(existing_node
) => existing_node
,
92 let parent_scope
= match parent_node
{
93 Some(ref node
) => node
.scope
,
94 None
=> ptr
::null_mut()
96 let namespace_name
= token
::get_name(name
);
97 let namespace_name
= CString
::new(namespace_name
.as_bytes()).unwrap();
99 llvm
::LLVMDIBuilderCreateNameSpace(
102 namespace_name
.as_ptr(),
103 // cannot reconstruct file ...
105 // ... or line information, but that's not so important.
109 let node
= Rc
::new(NamespaceTreeNode
{
112 parent
: parent_node
.map(|parent
| parent
.downgrade()),
115 debug_context(cx
).namespace_map
.borrow_mut()
116 .insert(current_key
.clone(), node
.clone());
122 parent_node
= Some(current_node
);
128 cx
.sess().bug(&format
!("debuginfo::namespace_for_item(): \
129 path too short for {:?}",