This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[gcjx] Patch: FYI: name mangling fixes
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 17 Apr 2005 15:24:24 -0600
- Subject: [gcjx] Patch: FYI: name mangling fixes
- Reply-to: tromey at redhat dot com
I'm checking this in on the gcjx branch.
This fixes a few bugs in name mangling.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* model/class.cc (get_output_name): New method.
* model/class.hh (model_class::get_output_name): Declare.
* aot/mangle.cc (update): Use get_output_name. Mangle non-ascii
characters.
* header/cni.cc (write_namespaces): Use get_output_name.
(write_method): Likewise.
Index: aot/mangle.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/aot/Attic/mangle.cc,v
retrieving revision 1.1.2.6
diff -u -r1.1.2.6 mangle.cc
--- aot/mangle.cc 8 Mar 2005 00:59:04 -0000 1.1.2.6
+++ aot/mangle.cc 17 Apr 2005 21:13:06 -0000
@@ -100,10 +100,110 @@
}
void
-mangler::update (const std::string &s)
+mangler::update (const std::string &name)
{
+ // If we see a substring that is a literal "__U", we have to
+ // remangle it as "__U_". This keeps track of where we are in the
+ // substring.
+ int state = 0;
+ const char *search = "__U";
+
+ std::ostringstream output;
+ unsigned int i = 0;
+ while (i < name.length ())
+ {
+ jchar ch;
+ unsigned char c = name[i++];
+ unsigned char c1, c2;
+ if (c < 128)
+ ch = c;
+ else
+ {
+ if ((c & 0xe0) == 0xc0)
+ {
+ assert (i < name.length ()); // FIXME
+ c1 = name[i++];
+ if ((c1 & 0xc0) == 0x80)
+ {
+ jchar r = (jchar) (((c & 0x1f) << 6) + (c1 & 0x3f));
+ /* Check for valid 2-byte characters. We explicitly
+ allow \0 because this encoding is common in the
+ Java world. */
+ if (r == 0 || (r >= 0x80 && r <= 0x7ff))
+ ch = r;
+ }
+ else
+ abort (); // FIXME
+ }
+ else if ((c & 0xf0) == 0xe0)
+ {
+ assert (i < name.length ()); // FIXME
+ c1 = name[i++];
+ if ((c1 & 0xc0) == 0x80)
+ {
+ assert (i < name.length ()); // FIXME
+ c2 = name[i++];
+ if ((c2 & 0xc0) == 0x80)
+ {
+ jchar r = (jchar) ((( c & 0xf) << 12) +
+ (( c1 & 0x3f) << 6)
+ + (c2 & 0x3f));
+ /* Check for valid 3-byte characters.
+ Don't allow surrogate, \ufffe or \uffff. */
+ if (r >= 0x800
+ && ! (r >= 0xd800 && r <= 0xdfff)
+ && r != 0xfffe && r != 0xffff)
+ ch = r;
+ else
+ abort (); // FIXME
+ }
+ else
+ abort (); // FIXME
+ }
+ else
+ abort (); // FIXME
+ }
+ else
+ abort (); // FIXME
+ }
+
+ if (ch == search[state])
+ {
+ ++state;
+ if (search[state] == '\0')
+ {
+ // Emit the mangled form.
+ output << "__U_";
+ state = 0;
+ }
+ }
+ else
+ {
+ // Emit any characters we recognized.
+ for (int i = 0; i < state; ++i)
+ output << search[i];
+ state = 0;
+
+ if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
+ || (ch >= '0' && ch <= '9') || ch == '_' || ch == '$')
+ {
+ // ASCII character, just emit.
+ output << char (ch);
+ }
+ else
+ {
+ // "Unicode" character, must mangle.
+ char buf[20];
+ sprintf (buf, "__U%x_", int (ch));
+ output << buf;
+ }
+ }
+ }
+
+ std::string s = output.str ();
char buf[20];
sprintf (buf, "%d", s.length ());
+
result += buf + s;
}
@@ -185,7 +285,7 @@
model_class *k = assert_cast<model_class *> (t);
if (k->get_package ())
update (k->get_package ());
- update (k->get_name ());
+ update (k->get_output_name ());
enter = true;
// This is a hack: we know only the outer-most class
// reference will be called with is_pointer == false.
Index: header/cni.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/header/Attic/cni.cc,v
retrieving revision 1.1.2.6
diff -u -r1.1.2.6 cni.cc
--- header/cni.cc 17 Apr 2005 20:47:43 -0000 1.1.2.6
+++ header/cni.cc 17 Apr 2005 21:13:06 -0000
@@ -369,9 +369,7 @@
}
indent (out, indentation);
- out << "class "
- << get_simple_name (split (klass->get_fully_qualified_name (), '.'))
- << ";" << std::endl;
+ out << "class " << klass->get_output_name () << ";" << std::endl;
}
move_to_package (out, current_package, base, indentation);
@@ -464,11 +462,7 @@
#endif
if (meth->constructor_p ())
- {
- std::string s
- = meth->get_declaring_class ()->get_fully_qualified_name ();
- out << get_simple_name (split (s, '.'));
- }
+ out << meth->get_declaring_class ()->get_output_name ();
else
{
if (meth->static_p ())
Index: model/class.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/model/Attic/class.cc,v
retrieving revision 1.1.2.9
diff -u -r1.1.2.9 class.cc
--- model/class.cc 27 Mar 2005 03:03:46 -0000 1.1.2.9
+++ model/class.cc 17 Apr 2005 21:13:07 -0000
@@ -368,6 +368,14 @@
}
std::string
+model_class::get_output_name () const
+{
+ if (declaring_class)
+ return declaring_class->get_name () + "$" + get_assigned_name ();
+ return name;
+}
+
+std::string
model_class::get_signature_fragment ()
{
std::string result;
Index: model/class.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/model/Attic/class.hh,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 class.hh
--- model/class.hh 27 Mar 2005 03:05:09 -0000 1.1.2.3
+++ model/class.hh 17 Apr 2005 21:13:07 -0000
@@ -304,6 +304,10 @@
return name;
}
+ /// Like get_name() but returns a constructed name if the class is
+ /// inner or anonymous.
+ std::string get_output_name () const;
+
/// Returns this class' name in the form "java.lang.Object".
std::string get_fully_qualified_name ();