summaryrefslogtreecommitdiff
path: root/gcc/java/mangle.c
diff options
context:
space:
mode:
authorgreen <green@138bc75d-0d04-0410-961f-82ee72b054a4>1998-09-06 15:36:06 +0000
committergreen <green@138bc75d-0d04-0410-961f-82ee72b054a4>1998-09-06 15:36:06 +0000
commit377029eb64eb54a4d6aa7fbfe06230ae65cb086b (patch)
treeb78f906318225a5e7bd3471f008be772727bdcea /gcc/java/mangle.c
parentb13f7168a0f35f0d6cc011a7dda0aea51c3d2780 (diff)
downloadgcc-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.c163
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;
+ }
+ }
+}