[PATCH] PR libstdc++/12736 / C++-ABI demangler update.
Carlo Wood
carlo@alinoe.com
Wed Dec 3 18:39:00 GMT 2003
This is a new patch - I removed the IEEE decoding because there was too
much oppostion. This version prints out the literal mangled string
of the floating value instead - but allows to override the printing
of floating values by those who use the demangle.h header.
--------
2003-12-03 Carlo Wood <carlo@alinoe.com>
PR libstdc++/13045
* bits/demangle.h
namespace __gnu_cxx::demangler
(enum substitution_nt): Removed trailing comma.
(session<Allocator>::decode_real): Added.
(session<Allocator>::decode_literal): Call decode_real for
floating literals.
(session<Allocator>::decode_type_with_postfix): Put the postfix
of the return type of (member) functions after the function
instead of after the return type. Also, put a space after the
prefix of qualified function pointers: "int (* const<space>".
* src/demangle.cc: include most dependent header file first.
* testsuite/demangle/regression/cw-16.cc: Updated one
and added three tests.
Testsuite runs ok. Bootstrap works too of course.
Patch attached.
--
Carlo Wood <carlo@alinoe.com>
-------------- next part --------------
Index: libstdc++-v3/include/bits/demangle.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/demangle.h,v
retrieving revision 1.11
diff -u -d -p -r1.11 demangle.h
--- libstdc++-v3/include/bits/demangle.h 12 Nov 2003 02:18:36 -0000 1.11
+++ libstdc++-v3/include/bits/demangle.h 3 Dec 2003 18:07:49 -0000
@@ -91,7 +91,7 @@ namespace __gnu_cxx
template_template_param,
nested_name_prefix,
nested_name_template_prefix,
- unscoped_template_name,
+ unscoped_template_name
};
struct substitution_st
@@ -353,6 +353,8 @@ namespace __gnu_cxx
#endif
{ }
+ virtual ~session() { }
+
static int
decode_encoding(string_type& output, char const* input, int len);
@@ -425,6 +427,8 @@ namespace __gnu_cxx
bool decode_unscoped_name(string_type& output);
bool decode_non_negative_decimal_integer(string_type& output);
bool decode_special_name(string_type& output);
+ protected:
+ virtual bool decode_real(string_type& output, size_t size_of_real);
};
template<typename Allocator>
@@ -881,6 +885,26 @@ namespace __gnu_cxx
template<typename Allocator>
bool
+ session<Allocator>::decode_real(string_type& output, size_t size_of_real)
+ {
+ _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_real");
+
+ output += '[';
+ char c = current();
+ for(size_t nibble_cnt = 0; nibble_cnt < 2 * size_of_real; ++nibble_cnt)
+ {
+ if (c < '0' || c > 'f' || (c > '9' && c < 'a'))
+ _GLIBCXX_DEMANGLER_FAILURE;
+ output += c;
+ c = next();
+ }
+ output += ']';
+
+ _GLIBCXX_DEMANGLER_RETURN;
+ }
+
+ template<typename Allocator>
+ bool
session<Allocator>::decode_literal(string_type& output)
{
_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_literal");
@@ -925,7 +949,15 @@ namespace __gnu_cxx
_GLIBCXX_DEMANGLER_FAILURE;
output += ')';
}
- if (!decode_number(output))
+ if (c >= 'd' && c <= 'g')
+ {
+ size_t size_of_real = (c == 'd') ? sizeof(double) :
+ ((c == 'f') ? sizeof(float) :
+ (c == 'e') ? sizeof(long double) : 16);
+ if (!decode_real(output, size_of_real))
+ _GLIBCXX_DEMANGLER_FAILURE;
+ }
+ else if (!decode_number(output))
_GLIBCXX_DEMANGLER_FAILURE;
#ifdef _GLIBCXX_DEMANGLER_STYLE_LITERAL
if (c == 'j' || c == 'm' || c == 'y')
@@ -1508,8 +1540,8 @@ namespace __gnu_cxx
// <Q>F<R><B>E ==> R (Q)B "<R>", "<B>" (<B> recursive)
// and "F<R><B>E".
//
- // Note that if <R> has postfix qualifiers (an array), then those
- // are added AFTER the (member) function type. For example:
+ // Note that if <R> has postfix qualifiers (an array or function), then
+ // those are added AFTER the (member) function type. For example:
// <Q>FPA<R><B>E ==> R (*(Q)B) [], where the PA added the prefix
// "(*" and the postfix ") []".
//
@@ -1863,7 +1895,8 @@ namespace __gnu_cxx
// Return type.
// Constructors, destructors and conversion operators don't
// have a return type, but seem to never get here.
- if (!decode_type_with_postfix(prefix, postfix))
+ string_type return_type_postfix;
+ if (!decode_type_with_postfix(prefix, return_type_postfix))
// substitution: <R> recursive
{
failure = true;
@@ -1885,9 +1918,10 @@ namespace __gnu_cxx
add_substitution(start_pos, type);
// substitution: all qualified types if any.
qualifiers->decode_qualifiers(prefix, postfix);
- prefix += ")";
- prefix += bare_function_type;
- prefix += member_function_qualifiers;
+ postfix += ")";
+ postfix += bare_function_type;
+ postfix += member_function_qualifiers;
+ postfix += return_type_postfix;
goto decode_type_exit;
}
qualifiers->add_qualifier_start(pointer_to_member, start_pos,
@@ -1929,17 +1963,19 @@ namespace __gnu_cxx
// substitution: "<R>", "<B>" (<B> recursive) and "F<R><B>E".
// Return type.
- if (!decode_type_with_postfix(prefix, postfix))
+ string_type return_type_postfix;
+ if (!decode_type_with_postfix(prefix, return_type_postfix))
// Substitution: "<R>".
{
failure = true;
break;
}
- // Only array (pointer) types have a postfix.
- // In that case we don't want the space but
- // expect something like prefix is "int (*"
- // and postfix is ") [1]".
- if (postfix.size() == 0)
+ // Only array and function (pointer) types have a postfix.
+ // In that case we don't want the space but expect something
+ // like prefix is "int (*" and postfix is ") [1]".
+ // We do want the space if this pointer is qualified.
+ if (return_type_postfix.size() == 0 ||
+ (prefix.size() > 0 && *prefix.rbegin() != '*'))
prefix += ' ';
prefix += '(';
string_type bare_function_type;
@@ -1953,10 +1989,11 @@ namespace __gnu_cxx
add_substitution(start_pos, type); // Substitution: "F<R><B>E".
qualifiers->decode_qualifiers(prefix, postfix);
// substitution: all qualified types, if any.
- prefix += ")";
+ postfix += ")";
if (extern_C)
- prefix += " [extern \"C\"] ";
- prefix += bare_function_type;
+ postfix += " [extern \"C\"] ";
+ postfix += bare_function_type;
+ postfix += return_type_postfix;
break;
}
case 'T':
Index: libstdc++-v3/src/demangle.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/demangle.cc,v
retrieving revision 1.3
diff -u -d -p -r1.3 demangle.cc
--- libstdc++-v3/src/demangle.cc 2 Oct 2003 14:29:26 -0000 1.3
+++ libstdc++-v3/src/demangle.cc 3 Dec 2003 18:07:51 -0000
@@ -28,8 +28,8 @@
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
-#include <cxxabi.h>
#include <bits/demangle.h>
+#include <cxxabi.h>
// __cxa_demangle
//
Index: libstdc++-v3/testsuite/demangle/regression/cw-16.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/demangle/regression/cw-16.cc,v
retrieving revision 1.3
diff -u -d -p -r1.3 cw-16.cc
--- libstdc++-v3/testsuite/demangle/regression/cw-16.cc 12 Nov 2003 02:18:37 -0000 1.3
+++ libstdc++-v3/testsuite/demangle/regression/cw-16.cc 3 Dec 2003 18:07:51 -0000
@@ -36,11 +36,18 @@ verify_demangle("_Z1fILi5E1AEvN1CIXqugtT
verify_demangle("_Z1fILi5EEvN1AIXcvimlT_Li22EEE1qE",
"void f<5>(A<(int)((5) * (22))>::q)");
verify_demangle("_Z1fPFYPFiiEiE",
- "f(int (*)(int) (*) [extern \"C\"] (int))");
+ "f(int (*(*) [extern \"C\"] (int))(int))");
verify_demangle("_Z1fI1XENT_1tES2_",
"X::t f<X>(X::t)");
verify_demangle("_Z1fILi5E1AEvN1CIXstN1T1tEEXszsrS2_1tEE1qE",
"void f<5, A>(C<sizeof (T::t), sizeof (T::t)>::q)");
+// 2003/12/03, libstdc++/13045
+verify_demangle("_Z1fILi1ELc120EEv1AIXplT_cviLd4028ae147ae147aeEEE",
+ "void f<1, (char)120>(A<(1) + ((int)((double)[4028ae147ae147ae]))>)");
+verify_demangle("_Z1fILi1ELc120EEv1AIXplT_cviLf3f800000EEE",
+ "void f<1, (char)120>(A<(1) + ((int)((float)[3f800000]))>)");
+verify_demangle("_Z9hairyfuncM1YKFPVPFrPA2_PM1XKFKPA3_ilEPcEiE",
+ "hairyfunc(int (* const (X::** (* restrict (* volatile* (Y::*)(int) const)(char*)) [2])(long) const) [3])");
return 0;
}
More information about the Libstdc++
mailing list