]>
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
;
18 use trans
::common
::CrateContext
;
19 use middle
::ty
::{self, ClosureTyper}
;
21 use std
::ffi
::CString
;
23 use std
::rc
::{Rc, Weak}
;
25 use syntax
::parse
::token
;
27 pub struct NamespaceTreeNode
{
30 pub parent
: Option
<Weak
<NamespaceTreeNode
>>,
33 impl NamespaceTreeNode
{
34 pub fn mangled_name_of_contained_item(&self, item_name
: &str) -> String
{
35 fn fill_nested(node
: &NamespaceTreeNode
, output
: &mut String
) {
37 Some(ref parent
) => fill_nested(&*parent
.upgrade().unwrap(), output
),
40 let string
= token
::get_name(node
.name
);
41 output
.push_str(&format
!("{}", string
.len()));
42 output
.push_str(&string
);
45 let mut name
= String
::from("_ZN");
46 fill_nested(self, &mut name
);
47 name
.push_str(&format
!("{}", item_name
.len()));
48 name
.push_str(item_name
);
54 pub fn crate_root_namespace
<'a
>(cx
: &'a CrateContext
) -> &'a
str {
55 &cx
.link_meta().crate_name
58 pub fn namespace_for_item(cx
: &CrateContext
, def_id
: ast
::DefId
) -> Rc
<NamespaceTreeNode
> {
59 ty
::with_path(cx
.tcx(), def_id
, |path
| {
60 // prepend crate name if not already present
61 let krate
= if def_id
.krate
== ast
::LOCAL_CRATE
{
62 let crate_namespace_name
= token
::intern(crate_root_namespace(cx
));
63 Some(ast_map
::PathMod(crate_namespace_name
))
67 let mut path
= krate
.into_iter().chain(path
).peekable();
69 let mut current_key
= Vec
::new();
70 let mut parent_node
: Option
<Rc
<NamespaceTreeNode
>> = None
;
72 // Create/Lookup namespace for each element of the path.
74 // Emulate a for loop so we can use peek below.
75 let path_element
= match path
.next() {
79 // Ignore the name of the item (the last path element).
80 if path
.peek().is_none() {
84 let name
= path_element
.name();
85 current_key
.push(name
);
87 let existing_node
= debug_context(cx
).namespace_map
.borrow()
88 .get(¤t_key
).cloned();
89 let current_node
= match existing_node
{
90 Some(existing_node
) => existing_node
,
93 let parent_scope
= match parent_node
{
94 Some(ref node
) => node
.scope
,
95 None
=> ptr
::null_mut()
97 let namespace_name
= token
::get_name(name
);
98 let namespace_name
= CString
::new(namespace_name
.as_bytes()).unwrap();
100 llvm
::LLVMDIBuilderCreateNameSpace(
103 namespace_name
.as_ptr(),
104 // cannot reconstruct file ...
106 // ... or line information, but that's not so important.
110 let node
= Rc
::new(NamespaceTreeNode
{
113 parent
: parent_node
.map(|parent
| parent
.downgrade()),
116 debug_context(cx
).namespace_map
.borrow_mut()
117 .insert(current_key
.clone(), node
.clone());
123 parent_node
= Some(current_node
);
129 cx
.sess().bug(&format
!("debuginfo::namespace_for_item(): \
130 path too short for {:?}",