about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-09-02 22:34:37 -0700
committerAlex Crichton <alex@alexcrichton.com>2013-09-04 23:28:23 -0700
commit7baff57f268eff79cd8ed6a8d7fd48d4b3f81878 (patch)
treed0784b2dcf15ac1ac75acd254b3872dbc835dc24 /src/libsyntax
parent36a4af49e0d66026e8ee7d156b2631208c4de2e5 (diff)
downloadrust-7baff57f268eff79cd8ed6a8d7fd48d4b3f81878.tar.gz
rust-7baff57f268eff79cd8ed6a8d7fd48d4b3f81878.zip
Improve name mangling for gdb
Remove __extensions__ from method symbols as well as the meth_XXX. The XXX is
now used to append a few characters at the end of the name of the symbol.

Closes #6602
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast_map.rs69
1 files changed, 40 insertions, 29 deletions
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index cb1c0eab720..1165ca0c68f 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -16,20 +16,20 @@ use ast_util;
 use codemap::Span;
 use codemap;
 use diagnostic::span_handler;
+use parse::token::get_ident_interner;
 use parse::token::ident_interner;
 use parse::token::special_idents;
 use print::pprust;
 use visit::{Visitor, fn_kind};
 use visit;
 
-use std::hash;
 use std::hashmap::HashMap;
 use std::vec;
 
 #[deriving(Clone, Eq)]
 pub enum path_elt {
     path_mod(Ident),
-    path_name(Ident)
+    path_name(Ident),
 
     // A pretty name can come from an `impl` block. We attempt to select a
     // reasonable name for debuggers to see, but to guarantee uniqueness with
@@ -98,8 +98,8 @@ pub struct Ctx {
 }
 
 impl Ctx {
-    fn extend(&self, elt: Ident) -> @path {
-        @vec::append(self.path.clone(), [path_name(elt)])
+    fn extend(&self, elt: path_elt) -> @path {
+        @vec::append(self.path.clone(), [elt])
     }
 
     fn map_method(&mut self,
@@ -120,7 +120,7 @@ impl Ctx {
                       struct_def: @ast::struct_def,
                       parent_node: ast_node,
                       ident: ast::Ident) {
-        let p = self.extend(ident);
+        let p = self.extend(path_name(ident));
 
         // If this is a tuple-like struct, register the constructor.
         match struct_def.ctor_id {
@@ -196,6 +196,28 @@ impl Ctx {
 
         visit::walk_pat(self, pat, ());
     }
+
+    fn impl_pretty_name(&self, trait_ref: &Option<trait_ref>,
+                        ty: &Ty, default: Ident) -> path_elt {
+        let itr = get_ident_interner();
+        let ty_ident = match ty.node {
+            ty_path(ref path, _, _) => path.segments.last().identifier,
+            _ => default
+        };
+        let hash = (trait_ref, ty).hash();
+        match *trait_ref {
+            None => path_pretty_name(ty_ident, hash),
+            Some(ref trait_ref) => {
+                // XXX: this dollar sign is actually a relic of being one of the
+                //      very few valid symbol names on unix. These kinds of
+                //      details shouldn't be exposed way up here in the ast.
+                let s = fmt!("%s$%s",
+                             itr.get(trait_ref.path.segments.last().identifier.name),
+                             itr.get(ty_ident.name));
+                path_pretty_name(Ident::new(itr.gensym(s)), hash)
+            }
+        }
+    }
 }
 
 impl Visitor<()> for Ctx {
@@ -205,40 +227,27 @@ impl Visitor<()> for Ctx {
         self.map.insert(i.id, node_item(i, item_path));
         match i.node {
             item_impl(_, ref maybe_trait, ref ty, ref ms) => {
+                // Right now the ident on impls is __extensions__ which isn't
+                // very pretty when debugging, so attempt to select a better
+                // name to use.
+                let elt = self.impl_pretty_name(maybe_trait, ty, i.ident);
+
                 let impl_did = ast_util::local_def(i.id);
                 for m in ms.iter() {
-                    let extended = { self.extend(i.ident) };
+                    let extended = { self.extend(elt) };
                     self.map_method(impl_did, extended, *m, false)
                 }
 
-                // Right now the ident on impls is __extensions__ which isn't
-                // very pretty when debugging, so attempt to select a better
-                // name to use.
-                let name = match *maybe_trait {
-                    Some(ref trait_ref) => {
-                        trait_ref.path.segments.last().identifier
-                    }
-                    None => {
-                        match ty.node {
-                            ty_path(ref p, _, _) => {
-                                p.segments.last().identifier
-                            }
-                            // oh well, just give up for now
-                            _ => { i.ident }
-                        }
-                    }
-                };
-
-                let hash = hash::hash_keyed_2(maybe_trait, ty, 0, 0);
-                self.path.push(path_pretty_name(name, hash));
+                self.path.push(elt);
             }
             item_enum(ref enum_definition, _) => {
                 for v in (*enum_definition).variants.iter() {
+                    let elt = path_name(i.ident);
                     // FIXME #2543: bad clone
                     self.map.insert(v.node.id,
                                     node_variant((*v).clone(),
                                                  i,
-                                                 self.extend(i.ident)));
+                                                 self.extend(elt)));
                 }
             }
             item_foreign_mod(ref nm) => {
@@ -257,7 +266,9 @@ impl Visitor<()> for Ctx {
                                                       // FIXME (#2543)
                                                       if nm.sort ==
                                                             ast::named {
-                                                        self.extend(i.ident)
+                                                          let e = path_name(
+                                                              i.ident);
+                                                          self.extend(e)
                                                       } else {
                                                         // Anonymous extern
                                                         // mods go in the
@@ -276,7 +287,7 @@ impl Visitor<()> for Ctx {
                     self.map.insert(p.ref_id, node_item(i, item_path));
                 }
                 for tm in methods.iter() {
-                    let ext = { self.extend(i.ident) };
+                    let ext = { self.extend(path_name(i.ident)) };
                     let d_id = ast_util::local_def(i.id);
                     match *tm {
                         required(ref m) => {