summaryrefslogtreecommitdiff
path: root/gcc/java/mangle_name.c
diff options
context:
space:
mode:
authorapbianco <apbianco@138bc75d-0d04-0410-961f-82ee72b054a4>2001-02-09 00:32:11 +0000
committerapbianco <apbianco@138bc75d-0d04-0410-961f-82ee72b054a4>2001-02-09 00:32:11 +0000
commitbca8957b5389aac36dfe748a500ca0b3f7635edd (patch)
tree63a7dd46d1f2e24a7f154e95b10330dd27796201 /gcc/java/mangle_name.c
parente37e4a504bb2a22e41828a5decda17fa8dc5117c (diff)
downloadgcc-bca8957b5389aac36dfe748a500ca0b3f7635edd.tar.gz
2001-02-08 Alexandre Petit-Bianco <apbianco@cygnus.com>
* Make-lang.in (JAVA_OBJS): Added java/mangle_name.o (JVGENMAIN_OBJS): Likewise. * java-tree.h (append_gpp_mangled_name): New prototype. * jcf-parse.c (ggc_mark_jcf): Argument now `void *.' Removed cast calling `gcc_add_root.' * jvgenmain.c (mangle_obstack): New global, initialized. (main): Use it. (do_mangle_class): Constify local `ptr.' Removed macro `MANGLE_NAME.' Removed cast in `for.' Call append_gpp_mangle_name and update `count' if necessary. Use `mangle_obstack.' * mangle.c (append_unicode_mangled_name): Removed. (append_gpp_mangled_name): Likewise. (unicode_mangling_length): Likewise. (mangle_member_name): Return type set to `void.' (mangle_field_decl): Don't append `U' in escaped names. (mangle_method_decl): Likewise. (mangle_member_name): Just use `append_gpp_mangled_name.' * mangle_name.c: New file. (http://gcc.gnu.org/ml/gcc-patches/2001-02/msg00492.html) git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@39552 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java/mangle_name.c')
-rw-r--r--gcc/java/mangle_name.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/gcc/java/mangle_name.c b/gcc/java/mangle_name.c
new file mode 100644
index 00000000000..b074f1ed212
--- /dev/null
+++ b/gcc/java/mangle_name.c
@@ -0,0 +1,223 @@
+/* Shared functions related to mangling names for the GNU compiler
+ for the Java(TM) language.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+Java and all Java-based marks are trademarks or registered trademarks
+of Sun Microsystems, Inc. in the United States and other countries.
+The Free Software Foundation is independent of Sun Microsystems, Inc. */
+
+/* Written by Alexandre Petit-Bianco <apbianco@cygnus.com> */
+
+#include "config.h"
+#include "system.h"
+#include "jcf.h"
+#include "tree.h"
+#include "java-tree.h"
+#include "obstack.h"
+#include "toplev.h"
+#include "obstack.h"
+
+static void append_unicode_mangled_name PARAMS ((const char *, int));
+#ifndef HAVE_AS_UTF8
+static int unicode_mangling_length PARAMS ((const char *, int));
+#endif
+
+extern struct obstack *mangle_obstack;
+
+/* If the assembler doesn't support UTF8 in symbol names, some
+ characters might need to be escaped. */
+
+#ifndef HAVE_AS_UTF8
+
+/* Assuming (NAME, LEN) is a Utf8-encoding string, emit the string
+ appropriately mangled (with Unicode escapes if needed) to
+ MANGLE_OBSTACK. Note that `java', `lang' and `Object' are used so
+ frequently that they could be cached. */
+
+void
+append_gpp_mangled_name (name, len)
+ const char *name;
+ int len;
+{
+ int encoded_len = unicode_mangling_length (name, len);
+ int needs_escapes = encoded_len > 0;
+ char buf[6];
+
+ sprintf (buf, "%d", (needs_escapes ? encoded_len : len));
+ obstack_grow (mangle_obstack, buf, strlen (buf));
+
+ if (needs_escapes)
+ append_unicode_mangled_name (name, len);
+ else
+ obstack_grow (mangle_obstack, name, len);
+}
+
+/* Assuming (NAME, LEN) is a Utf8-encoded string, emit the string
+ appropriately mangled (with Unicode escapes) to MANGLE_OBSTACK.
+ Characters needing an escape are encoded `__UNN_' to `__UNNNN_', in
+ which case `__U' will be mangled `__U_'. `$' is mangled `$' or
+ __U24_ according to NO_DOLLAR_IN_LABEL. */
+
+static void
+append_unicode_mangled_name (name, len)
+ const char *name;
+ int len;
+{
+ const unsigned char *ptr;
+ const unsigned char *limit = (const unsigned char *)name + len;
+ int uuU = 0;
+ for (ptr = (const unsigned char *) name; ptr < limit; )
+ {
+ int ch = UTF8_GET(ptr, limit);
+
+ if ((ch >= '0' && ch <= '9')
+#ifndef NO_DOLLAR_IN_LABEL
+ || ch == '$'
+#endif
+ || (ch >= 'a' && ch <= 'z')
+ || (ch >= 'A' && ch <= 'Z' && ch != 'U'))
+ obstack_1grow (mangle_obstack, ch);
+ /* Everything else needs encoding */
+ else
+ {
+ char buf [9];
+ if (ch == '_' || ch == 'U')
+ {
+ /* Prepare to recognize __U */
+ if (ch == '_' && (uuU < 3))
+ {
+ uuU++;
+ obstack_1grow (mangle_obstack, ch);
+ }
+ /* We recognize __U that we wish to encode
+ __U_. Finish the encoding. */
+ else if (ch == 'U' && (uuU == 2))
+ {
+ uuU = 0;
+ obstack_grow (mangle_obstack, "U_", 2);
+ }
+ continue;
+ }
+ sprintf (buf, "__U%x_", ch);
+ obstack_grow (mangle_obstack, buf, strlen (buf));
+ uuU = 0;
+ }
+ }
+}
+
+/* Assuming (NAME, LEN) is a Utf8-encoding string, calculate the
+ length of the string as mangled (a la g++) including Unicode
+ escapes. If no escapes are needed, return 0. */
+
+static int
+unicode_mangling_length (name, len)
+ const char *name;
+ int len;
+{
+ const unsigned char *ptr;
+ const unsigned char *limit = (const unsigned char *)name + len;
+ int need_escapes = 0; /* Whether we need an escape or not */
+ int num_chars = 0; /* Number of characters in the mangled name */
+ int uuU = 0; /* Help us to find __U. 0: '_', 1: '__' */
+ for (ptr = (const unsigned char *) name; ptr < limit; )
+ {
+ int ch = UTF8_GET(ptr, limit);
+
+ if (ch < 0)
+ error ("internal error - invalid Utf8 name");
+ if ((ch >= '0' && ch <= '9')
+#ifndef NO_DOLLAR_IN_LABEL
+ || ch == '$'
+#endif
+ || (ch >= 'a' && ch <= 'z')
+ || (ch >= 'A' && ch <= 'Z' && ch != 'U'))
+ num_chars++;
+ /* Everything else needs encoding */
+ else
+ {
+ int encoding_length = 2;
+
+ if (ch == '_' || ch == 'U')
+ {
+ /* Prepare to recognize __U */
+ if (ch == '_' && (uuU < 3))
+ {
+ num_chars++;
+ uuU++;
+ }
+ /* We recognize __U that we wish to encode __U_ */
+ else if (ch == 'U' && (uuU == 2))
+ {
+ num_chars += 2;
+ need_escapes = 1;
+ uuU = 0;
+ }
+ continue;
+ }
+
+ if (ch > 0xff)
+ encoding_length++;
+ if (ch > 0xfff)
+ encoding_length++;
+
+ num_chars += (4 + encoding_length);
+ need_escapes = 1;
+ uuU = 0;
+ }
+ }
+ if (need_escapes)
+ return num_chars;
+ else
+ return 0;
+}
+
+#else
+
+/* The assembler supports UTF8, we don't use escapes. Mangling is
+ simply <N>NAME. <N> is the number of UTF8 encoded characters that
+ are found in NAME. Note that `java', `lang' and `Object' are used
+ so frequently that they could be cached. */
+
+void
+append_gpp_mangled_name (name, len)
+ const char *name;
+ int len;
+{
+ const unsigned char *ptr;
+ const unsigned char *limit = (const unsigned char *)name + len;
+ int encoded_len;
+ char buf [6];
+
+ /* Compute the length of the string we wish to mangle. */
+ for (encoded_len = 0, ptr = (const unsigned char *) name;
+ ptr < limit; encoded_len++)
+ {
+ int ch = UTF8_GET(ptr, limit);
+
+ if (ch < 0)
+ error ("internal error - invalid Utf8 name");
+ }
+
+ sprintf (buf, "%d", encoded_len);
+ obstack_grow (mangle_obstack, buf, strlen (buf));
+ obstack_grow (mangle_obstack, name, len);
+}
+
+#endif /* HAVE_AS_UTF8 */