summaryrefslogtreecommitdiff
path: root/libiberty/cp-demangle.c
diff options
context:
space:
mode:
authorDJ Delorie <dj@delorie.com>2002-07-10 00:01:58 +0000
committerDJ Delorie <dj@delorie.com>2002-07-10 00:01:58 +0000
commitf95fbb813c7ab43fefa466a2ac3e958ab5b884a8 (patch)
treee9feff687078de9d9c6cc2d78dab3e58ff8c14b8 /libiberty/cp-demangle.c
parent38f9168b876f9e39819b706366d1600cd7f519af (diff)
downloadgdb-f95fbb813c7ab43fefa466a2ac3e958ab5b884a8.tar.gz
merge from gcc
Diffstat (limited to 'libiberty/cp-demangle.c')
-rw-r--r--libiberty/cp-demangle.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index e3ef42ce261..eece533e070 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;
}