oops - omitted from previous delta fixing UNIQUE_SECTION
[official-gcc.git] / gcc / java / mangle.c
blobd38a23a173e0d2cf857e40295f56c972f6ea8eb7
1 /* Functions related to mangling class names for the GNU compiler
2 for the Java(TM) language.
3 Copyright (C) 1998, 1999 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
26 /* Written by Per Bothner <bothner@cygnus.com> */
28 #include "config.h"
29 #include "system.h"
30 #include "jcf.h"
31 #include "tree.h"
32 #include "java-tree.h"
33 #include "obstack.h"
34 #include "toplev.h"
36 /* Assuming (NAME, LEN) is a Utf8-encoding string, calculate
37 the length of the string as mangled (a la g++) including Unicode escapes.
38 If no escapes are needed, return 0. */
40 int
41 unicode_mangling_length (name, len)
42 const char *name;
43 int len;
45 const unsigned char *ptr;
46 const unsigned char *limit = (const unsigned char *)name + len;
47 int need_escapes = 0;
48 int num_chars = 0;
49 int underscores = 0;
50 for (ptr = (const unsigned char *) name; ptr < limit; )
52 int ch = UTF8_GET(ptr, limit);
53 if (ch < 0)
54 error ("internal error - invalid Utf8 name");
55 if (ch >= '0' && ch <= '9')
56 need_escapes += num_chars == 0;
57 else if (ch == '_')
58 underscores++;
59 else if ((ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z'))
60 need_escapes++;
61 num_chars++;
63 if (need_escapes)
64 return num_chars + 4 * (need_escapes + underscores);
65 else
66 return 0;
69 /* Assuming (NAME, LEN) is a Utf8-encoding string, emit the string
70 appropriately mangled (with Unicode escapes) to OBSTACK. */
72 void
73 emit_unicode_mangled_name (obstack, name, len)
74 struct obstack *obstack;
75 const char *name;
76 int len;
78 const unsigned char *ptr;
79 const unsigned char *limit = (const unsigned char *)name + len;
80 for (ptr = (const unsigned char *) name; ptr < limit; )
82 int ch = UTF8_GET(ptr, limit);
83 int emit_escape;
84 if (ch < 0)
86 error ("internal error - bad Utf8 string");
87 break;
89 if (ch >= '0' && ch <= '9')
90 emit_escape = (ptr == (const unsigned char *) name);
91 else
92 emit_escape = (ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z');
93 if (emit_escape)
95 char buf[6];
96 sprintf (buf, "_%04x", ch);
97 obstack_grow (obstack, buf, 5);
99 else
101 obstack_1grow (obstack, ch);
106 /* Assuming (NAME, LEN) is a Utf8-encoding string, emit the string
107 appropriately mangled (with Unicode escapes if needed) to OBSTACK. */
109 void
110 append_gpp_mangled_name (obstack, name, len)
111 struct obstack *obstack;
112 const char *name;
113 int len;
115 int encoded_len = unicode_mangling_length (name, len);
116 int needs_escapes = encoded_len > 0;
117 char buf[6];
118 if (needs_escapes)
120 sprintf (buf, "U%d", encoded_len);
121 obstack_grow (obstack, buf, strlen(buf));
122 emit_unicode_mangled_name (obstack, name, len);
124 else
126 sprintf (buf, "%d", len);
127 obstack_grow (obstack, buf, strlen(buf));
128 obstack_grow (obstack, name, len);
132 /* Append the mangled name of a class named CLASSNAME onto OBSTACK. */
134 void
135 append_gpp_mangled_classtype (obstack, class_name)
136 struct obstack *obstack;
137 const char *class_name;
139 const char *ptr;
140 int qualifications = 0;
142 for (ptr = class_name; *ptr != '\0'; ptr++)
144 if (*ptr == '.')
145 qualifications++;
147 if (qualifications)
149 char buf[8];
150 if (qualifications >= 9)
151 sprintf (buf, "Q_%d_", qualifications + 1);
152 else
153 sprintf (buf, "Q%d", qualifications + 1);
154 obstack_grow (obstack, buf, strlen (buf));
156 for (ptr = class_name; ; ptr++)
158 if (ptr[0] == '.' || ptr[0] == '\0')
160 append_gpp_mangled_name (obstack, class_name, ptr - class_name);
161 if (ptr[0] == '\0')
162 break;
163 class_name = ptr + 1;