This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gcjx] Patch: FYI: name mangling fixes


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 ();
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]