diff options
author | apbianco <apbianco@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-02-09 00:32:11 +0000 |
---|---|---|
committer | apbianco <apbianco@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-02-09 00:32:11 +0000 |
commit | bca8957b5389aac36dfe748a500ca0b3f7635edd (patch) | |
tree | 63a7dd46d1f2e24a7f154e95b10330dd27796201 /gcc/java/mangle_name.c | |
parent | e37e4a504bb2a22e41828a5decda17fa8dc5117c (diff) | |
download | gcc-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.c | 223 |
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 */ |