diff options
author | DJ Delorie <dj@redhat.com> | 2002-07-10 00:01:58 +0000 |
---|---|---|
committer | DJ Delorie <dj@redhat.com> | 2002-07-10 00:01:58 +0000 |
commit | b851d07bfd7deab3fd46ac64b1c5d9b56f218676 (patch) | |
tree | f61fd90c89eff98d273a0e69f0ef9c04992a5f18 /libiberty/cp-demangle.c | |
parent | 7b210f262f6f2a1f9095ca307c051888e5b89d68 (diff) | |
download | gdb-b851d07bfd7deab3fd46ac64b1c5d9b56f218676.zip gdb-b851d07bfd7deab3fd46ac64b1c5d9b56f218676.tar.gz gdb-b851d07bfd7deab3fd46ac64b1c5d9b56f218676.tar.bz2 |
merge from gcc
Diffstat (limited to 'libiberty/cp-demangle.c')
-rw-r--r-- | libiberty/cp-demangle.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index e3ef42c..eece533 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -51,6 +51,8 @@ #include <string.h> #endif +#include <ctype.h> + #include "ansidecl.h" #include "libiberty.h" #include "dyn-string.h" @@ -1466,9 +1468,45 @@ demangle_identifier (dm, length, identifier) while (length-- > 0) { + int ch; if (end_of_name_p (dm)) return "Unexpected end of name in <identifier>."; - if (!dyn_string_append_char (identifier, next_char (dm))) + ch = next_char (dm); + + /* Handle extended Unicode characters. We encode them as __U{hex}_, + where {hex} omits leading 0's. For instance, '$' is encoded as + "__U24_". */ + if (ch == '_' + && peek_char (dm) == '_' + && peek_char_next (dm) == 'U') + { + char buf[10]; + int pos = 0; + advance_char (dm); advance_char (dm); length -= 2; + while (length-- > 0) + { + ch = next_char (dm); + if (!isxdigit (ch)) + break; + buf[pos++] = ch; + } + if (ch != '_' || length < 0) + return STATUS_ERROR; + if (pos == 0) + { + /* __U_ just means __U. */ + if (!dyn_string_append_cstr (identifier, "__U")) + return STATUS_ALLOCATION_FAILED; + continue; + } + else + { + buf[pos] = '\0'; + ch = strtol (buf, 0, 16); + } + } + + if (!dyn_string_append_char (identifier, ch)) return STATUS_ALLOCATION_FAILED; } |