[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