From 5398cab9ca3697b318d7c5e39508c1f12a059e17 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Mon, 1 May 2017 23:38:50 +0000 Subject: [PATCH] d-demangle.c (dlang_hexdigit): New function. libiberty/ChangeLog: * d-demangle.c (dlang_hexdigit): New function. (ascii2hex): Remove function. (dlang_parse_string): Update to call dlang_hexdigit. * testsuite/d-demangle-expected: Add tests. From-SVN: r247455 --- libiberty/ChangeLog | 7 ++ libiberty/d-demangle.c | 113 +++++++++++++----------- libiberty/testsuite/d-demangle-expected | 20 ++++- 3 files changed, 86 insertions(+), 54 deletions(-) diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 9bf22362cdb..14e7e3258f9 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,10 @@ +2017-05-02 Iain Buclaw + + * d-demangle.c (dlang_hexdigit): New function. + (ascii2hex): Remove function. + (dlang_parse_string): Update to call dlang_hexdigit. + * testsuite/d-demangle-expected: Add tests. + 2017-05-02 Iain Buclaw * d-demangle.c (strtol): Remove declaration. diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c index 3aaffe1f14f..ec5508e2777 100644 --- a/libiberty/d-demangle.c +++ b/libiberty/d-demangle.c @@ -223,6 +223,34 @@ dlang_number (const char *mangled, long *ret) return mangled; } +/* Extract the hex-digit from MANGLED, and assign the result to RET. + Return the remaining string on success or NULL on failure. */ +static const char * +dlang_hexdigit (const char *mangled, char *ret) +{ + char c; + + /* Return NULL if trying to extract something that isn't a hexdigit. */ + if (mangled == NULL || !ISXDIGIT (mangled[0]) || !ISXDIGIT (mangled[1])) + return NULL; + + c = mangled[0]; + if (!ISDIGIT (c)) + (*ret) = (c - (ISUPPER (c) ? 'A' : 'a') + 10); + else + (*ret) = (c - '0'); + + c = mangled[1]; + if (!ISDIGIT (c)) + (*ret) = (*ret << 4) | (c - (ISUPPER (c) ? 'A' : 'a') + 10); + else + (*ret) = (*ret << 4) | (c - '0'); + + mangled += 2; + + return mangled; +} + /* Demangle the calling convention from MANGLED and append it to DECL. Return the remaining string on success or NULL on failure. */ static const char * @@ -1070,22 +1098,6 @@ dlang_parse_real (string *decl, const char *mangled) return mangled; } -/* Convert VAL from an ascii hexdigit to value. */ -static char -ascii2hex (char val) -{ - if (val >= 'a' && val <= 'f') - return (val - 'a' + 10); - - if (val >= 'A' && val <= 'F') - return (val - 'A' + 10); - - if (val >= '0' && val <= '9') - return (val - '0'); - - return 0; -} - /* Extract the string value from MANGLED and append it to DECL. Return the remaining string on success or NULL on failure. */ static const char * @@ -1103,48 +1115,45 @@ dlang_parse_string (string *decl, const char *mangled) string_append (decl, "\""); while (len--) { - if (ISXDIGIT (mangled[0]) && ISXDIGIT (mangled[1])) + char val; + const char *endptr = dlang_hexdigit (mangled, &val); + + if (endptr == NULL) + return NULL; + + /* Sanitize white and non-printable characters. */ + switch (val) { - char a = ascii2hex (mangled[0]); - char b = ascii2hex (mangled[1]); - char val = (a << 4) | b; + case ' ': + string_append (decl, " "); + break; + case '\t': + string_append (decl, "\\t"); + break; + case '\n': + string_append (decl, "\\n"); + break; + case '\r': + string_append (decl, "\\r"); + break; + case '\f': + string_append (decl, "\\f"); + break; + case '\v': + string_append (decl, "\\v"); + break; - /* Sanitize white and non-printable characters. */ - switch (val) + default: + if (ISPRINT (val)) + string_appendn (decl, &val, 1); + else { - case ' ': - string_append (decl, " "); - break; - case '\t': - string_append (decl, "\\t"); - break; - case '\n': - string_append (decl, "\\n"); - break; - case '\r': - string_append (decl, "\\r"); - break; - case '\f': - string_append (decl, "\\f"); - break; - case '\v': - string_append (decl, "\\v"); - break; - - default: - if (ISPRINT (val)) - string_appendn (decl, &val, 1); - else - { - string_append (decl, "\\x"); - string_appendn (decl, mangled, 2); - } + string_append (decl, "\\x"); + string_appendn (decl, mangled, 2); } } - else - return NULL; - mangled += 2; + mangled = endptr; } string_append (decl, "\""); diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected index 0f511475faf..626d7c2d980 100644 --- a/libiberty/testsuite/d-demangle-expected +++ b/libiberty/testsuite/d-demangle-expected @@ -854,8 +854,8 @@ _D8demangle16__T4testVAyaa0_Zv demangle.test!("") # --format=dlang -_D8demangle30__T4testVAyaa7_20090a0d0c0b00Zv -demangle.test!(" \t\n\r\f\v\x00") +_D8demangle32__T4testVAyaa8_20090a0d0c0b00ffZv +demangle.test!(" \t\n\r\f\v\x00\xff") # --format=dlang _D8demangle22__T4testVAiA4i1i2i3i4Zv @@ -1076,10 +1076,18 @@ _D15__T4testVfe0p1Zv _D15__T4testVfe0p1Zv # --format=dlang +_D15__T4testVAyaa1_ +_D15__T4testVAyaa1_ +# +--format=dlang _D16__T4testVAyaa0aZv _D16__T4testVAyaa0aZv # --format=dlang +_D18__T4testVAyaa1_0GZv +_D18__T4testVAyaa1_0GZv +# +--format=dlang _D18__T4testVAyaa1_YYZv _D18__T4testVAyaa1_YYZv # @@ -1240,6 +1248,14 @@ _D8demangle32__T2fnTS3symVS3valS1a4_6e756c6cZ3fun13__T8positionZ13__T8confusesZ8 demangle.fn!(sym, val("null")).fun.position!().confuses!().demangle(void(const(char)) delegate) # --format=dlang +_D8demangle39__T2fnVAyaa12_d0bfd180d0b8d0bcd0b5d180Z2fnFZv +demangle.fn!("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xbc\xd0\xb5\xd1\x80").fn() +# +--format=dlang +_D8demangle26__T2fnVAyaa6_e4b896e7958cZ2fnFZv +demangle.fn!("\xe4\xb8\x96\xe7\x95\x8c").fn() +# +--format=dlang _D2gc11gctemplates56__T8mkBitmapTS3std5range13__T4iotaTiTiZ4iotaFiiZ6ResultZ8mkBitmapFNbNiNfPmmZv gc.gctemplates.mkBitmap!(std.range.iota!(int, int).iota(int, int).Result).mkBitmap(ulong*, ulong) # -- 2.30.2