about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPhilipp Brüschweiler <blei42@gmail.com>2013-06-05 21:40:49 +0200
committerPhilipp Brüschweiler <blei42@gmail.com>2013-06-05 22:21:25 +0200
commiteb627817206aa0ca5faf4ffb68f53da0f5ddbde5 (patch)
tree58a1dbc99b3afdb214864942a44ffa903169acf6 /src
parentde3000af8fa2aa9965453a2b8909c3f52244fb2e (diff)
downloadrust-eb627817206aa0ca5faf4ffb68f53da0f5ddbde5.tar.gz
rust-eb627817206aa0ca5faf4ffb68f53da0f5ddbde5.zip
rustc::back::link: redo symbol mangling
Handle more characters that appear in types, most notably <>): were
missing. Also the new scheme takes care that no two different input
strings result in the same mangled string, which was not the case before.

Fixes #6921
Diffstat (limited to 'src')
-rw-r--r--src/librustc/back/link.rs41
1 files changed, 26 insertions, 15 deletions
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs
index 9a27c293e48..451ce25be2f 100644
--- a/src/librustc/back/link.rs
+++ b/src/librustc/back/link.rs
@@ -633,26 +633,37 @@ pub fn get_symbol_hash(ccx: @CrateContext, t: ty::t) -> @str {
 
 // Name sanitation. LLVM will happily accept identifiers with weird names, but
 // gas doesn't!
+// gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $
 pub fn sanitize(s: &str) -> ~str {
     let mut result = ~"";
     for str::each_char(s) |c| {
         match c {
-          '@' => result += "_sbox_",
-          '~' => result += "_ubox_",
-          '*' => result += "_ptr_",
-          '&' => result += "_ref_",
-          ',' => result += "_",
-
-          '{' | '(' => result += "_of_",
-          'a' .. 'z'
-          | 'A' .. 'Z'
-          | '0' .. '9'
-          | '_' => result.push_char(c),
-          _ => {
-            if c > 'z' && char::is_XID_continue(c) {
-                result.push_char(c);
+            // Escape these with $ sequences
+            '@' => result += "$SP$",
+            '~' => result += "$UP$",
+            '*' => result += "$RP$",
+            '&' => result += "$BP$",
+            '<' => result += "$LT$",
+            '>' => result += "$GT$",
+            '(' => result += "$LP$",
+            ')' => result += "$RP$",
+            ',' => result += "$C$",
+
+            // '.' doesn't occur in types and functions, so reuse it
+            // for ':'
+            ':' => result.push_char('.'),
+
+            // These are legal symbols
+            'a' .. 'z'
+            | 'A' .. 'Z'
+            | '0' .. '9'
+            | '_' => result.push_char(c),
+
+            _ => {
+                if c > 'z' && char::is_XID_continue(c) {
+                    result.push_char(c);
+                }
             }
-          }
         }
     }