diff options
author | green <green@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-09-06 15:36:06 +0000 |
---|---|---|
committer | green <green@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-09-06 15:36:06 +0000 |
commit | 377029eb64eb54a4d6aa7fbfe06230ae65cb086b (patch) | |
tree | b78f906318225a5e7bd3471f008be772727bdcea /gcc/java/mangle.c | |
parent | b13f7168a0f35f0d6cc011a7dda0aea51c3d2780 (diff) | |
download | gcc-377029eb64eb54a4d6aa7fbfe06230ae65cb086b.tar.gz |
Initial revision
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@22299 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java/mangle.c')
-rw-r--r-- | gcc/java/mangle.c | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/gcc/java/mangle.c b/gcc/java/mangle.c new file mode 100644 index 00000000000..f303c926a08 --- /dev/null +++ b/gcc/java/mangle.c @@ -0,0 +1,163 @@ +/* Functions related to mangling class names for the GNU compiler + for the Java(TM) language. + Copyright (C) 1998 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 Per Bothner <bothner@cygnus.com> */ + +#include <stdio.h> +#include <string.h> +#include "config.h" +#include "jcf.h" +#include "obstack.h" + +/* 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. */ + +int +unicode_mangling_length (name, len) + char *name; + int len; +{ + unsigned char *ptr; + unsigned char *limit = (unsigned char *)name + len; + int need_escapes = 0; + int num_chars = 0; + int underscores = 0; + for (ptr = (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') + need_escapes += num_chars == 0; + else if (ch == '_') + underscores++; + else if ((ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z')) + need_escapes++; + num_chars++; + } + if (need_escapes) + return num_chars + 4 * (need_escapes + underscores); + else + return 0; +} + +/* Assuming (NAME, LEN) is a Utf8-encoding string, emit the string + appropriately mangled (with Unicode escapes) to OBSTACK. */ + +void +emit_unicode_mangled_name (obstack, name, len) + struct obstack *obstack; + char *name; +{ + unsigned char *ptr; + unsigned char *limit = (unsigned char *)name + len; + for (ptr = (unsigned char *) name; ptr < limit; ) + { + int ch = UTF8_GET(ptr, limit); + int emit_escape; + if (ch < 0) + { + error ("internal error - bad Utf8 string"); + break; + } + if (ch >= '0' && ch <= '9') + emit_escape = (ptr == (unsigned char*) name); + else + emit_escape = (ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z'); + if (emit_escape) + { + char buf[6]; + sprintf (buf, "_%04x", ch); + obstack_grow (obstack, buf, 5); + } + else + { + obstack_1grow (obstack, ch); + } + } +} + +/* Assuming (NAME, LEN) is a Utf8-encoding string, emit the string + appropriately mangled (with Unicode escapes if needed) to OBSTACK. */ + +void +append_gpp_mangled_name (obstack, name, len) + struct obstack *obstack; + char *name; + int len; +{ + int encoded_len = unicode_mangling_length (name, len); + int needs_escapes = encoded_len > 0; + char buf[6]; + if (needs_escapes) + { + sprintf (buf, "U%d", encoded_len); + obstack_grow (obstack, buf, strlen(buf)); + emit_unicode_mangled_name (obstack, name, len); + } + else + { + sprintf (buf, "%d", len); + obstack_grow (obstack, buf, strlen(buf)); + obstack_grow (obstack, name, len); + } +} + +/* Append the mangled name of a class named CLASSNAME onto OBSTACK. */ + +void +append_gpp_mangled_classtype (obstack, class_name) + struct obstack *obstack; + char *class_name; +{ + char *ptr; + int qualifications = 0; + + for (ptr = class_name; *ptr != '\0'; ptr++) + { + if (*ptr == '.') + qualifications++; + } + if (qualifications) + { + char buf[8]; + if (qualifications >= 9) + sprintf (buf, "Q_%d_", qualifications + 1); + else + sprintf (buf, "Q%d", qualifications + 1); + obstack_grow (obstack, buf, strlen (buf)); + } + for (ptr = class_name; ; ptr++) + { + if (ptr[0] == '.' || ptr[0] == '\0') + { + append_gpp_mangled_name (obstack, class_name, ptr - class_name); + if (ptr[0] == '\0') + break; + class_name = ptr + 1; + } + } +} |