diff options
| author | Philipp Brüschweiler <blei42@gmail.com> | 2013-06-05 21:40:49 +0200 |
|---|---|---|
| committer | Philipp Brüschweiler <blei42@gmail.com> | 2013-06-05 22:21:25 +0200 |
| commit | eb627817206aa0ca5faf4ffb68f53da0f5ddbde5 (patch) | |
| tree | 58a1dbc99b3afdb214864942a44ffa903169acf6 /src | |
| parent | de3000af8fa2aa9965453a2b8909c3f52244fb2e (diff) | |
| download | rust-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.rs | 41 |
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); + } } - } } } |
