Fix DealII type problems.
[official-gcc/Ramakrishna.git] / gcc / java / mangle_name.c
bloba75f5cad0907fb49e2a2d5ec2162ebd9fafa38c2
1 /* Shared functions related to mangling names for the GNU compiler
2 for the Java(TM) language.
3 Copyright (C) 2001, 2002, 2003, 2007 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC 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 3, or (at your option)
10 any later version.
12 GCC 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 GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>.
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc. */
25 /* Written by Alexandre Petit-Bianco <apbianco@cygnus.com> */
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "jcf.h"
32 #include "tree.h"
33 #include "java-tree.h"
34 #include "obstack.h"
35 #include "toplev.h"
37 static void append_unicode_mangled_name (const char *, int);
38 #ifndef HAVE_AS_UTF8
39 static int unicode_mangling_length (const char *, int);
40 #endif
42 extern struct obstack *mangle_obstack;
44 static int
45 utf8_cmp (const unsigned char *str, int length, const char *name)
47 const unsigned char *limit = str + length;
48 int i;
50 for (i = 0; name[i]; ++i)
52 int ch = UTF8_GET (str, limit);
53 if (ch != name[i])
54 return ch - name[i];
57 return str == limit ? 0 : 1;
60 /* A sorted list of all C++ keywords. If you change this, be sure
61 also to change the list in
62 libjava/classpath/tools/gnu/classpath/tools/javah/Keywords.java. */
63 static const char *const cxx_keywords[] =
65 "_Complex",
66 "__alignof",
67 "__alignof__",
68 "__asm",
69 "__asm__",
70 "__attribute",
71 "__attribute__",
72 "__builtin_va_arg",
73 "__complex",
74 "__complex__",
75 "__const",
76 "__const__",
77 "__extension__",
78 "__imag",
79 "__imag__",
80 "__inline",
81 "__inline__",
82 "__label__",
83 "__null",
84 "__real",
85 "__real__",
86 "__restrict",
87 "__restrict__",
88 "__signed",
89 "__signed__",
90 "__typeof",
91 "__typeof__",
92 "__volatile",
93 "__volatile__",
94 "and",
95 "and_eq",
96 "asm",
97 "auto",
98 "bitand",
99 "bitor",
100 "bool",
101 "break",
102 "case",
103 "catch",
104 "char",
105 "class",
106 "compl",
107 "const",
108 "const_cast",
109 "continue",
110 "default",
111 "delete",
112 "do",
113 "double",
114 "dynamic_cast",
115 "else",
116 "enum",
117 "explicit",
118 "export",
119 "extern",
120 "false",
121 "float",
122 "for",
123 "friend",
124 "goto",
125 "if",
126 "inline",
127 "int",
128 "long",
129 "mutable",
130 "namespace",
131 "new",
132 "not",
133 "not_eq",
134 "operator",
135 "or",
136 "or_eq",
137 "private",
138 "protected",
139 "public",
140 "register",
141 "reinterpret_cast",
142 "return",
143 "short",
144 "signed",
145 "sizeof",
146 "static",
147 "static_cast",
148 "struct",
149 "switch",
150 "template",
151 "this",
152 "throw",
153 "true",
154 "try",
155 "typedef",
156 "typeid",
157 "typename",
158 "typeof",
159 "union",
160 "unsigned",
161 "using",
162 "virtual",
163 "void",
164 "volatile",
165 "wchar_t",
166 "while",
167 "xor",
168 "xor_eq"
171 /* Return true if NAME is a C++ keyword. */
173 cxx_keyword_p (const char *name, int length)
175 int last = ARRAY_SIZE (cxx_keywords);
176 int first = 0;
177 int mid = (last + first) / 2;
178 int old = -1;
180 for (mid = (last + first) / 2;
181 mid != old;
182 old = mid, mid = (last + first) / 2)
184 int kwl = strlen (cxx_keywords[mid]);
185 int min_length = kwl > length ? length : kwl;
186 int r = utf8_cmp ((const unsigned char *) name, min_length, cxx_keywords[mid]);
188 if (r == 0)
190 int i;
191 /* We've found a match if all the remaining characters are `$'. */
192 for (i = min_length; i < length && name[i] == '$'; ++i)
194 if (i == length)
195 return 1;
196 r = 1;
199 if (r < 0)
200 last = mid;
201 else
202 first = mid;
204 return 0;
207 /* If NAME happens to be a C++ keyword, add `$'. */
208 #define MANGLE_CXX_KEYWORDS(NAME, LEN) \
209 do \
211 if (cxx_keyword_p ((NAME), (LEN))) \
213 char *tmp_buf = (char *)alloca ((LEN)+1); \
214 memcpy (tmp_buf, (NAME), (LEN)); \
215 tmp_buf[LEN]= '$'; \
216 (NAME) = tmp_buf; \
217 (LEN)++; \
220 while (0)
223 /* If the assembler doesn't support UTF8 in symbol names, some
224 characters might need to be escaped. */
226 #ifndef HAVE_AS_UTF8
228 /* Assuming (NAME, LEN) is a Utf8-encoding string, emit the string
229 appropriately mangled (with Unicode escapes if needed) to
230 MANGLE_OBSTACK. Note that `java', `lang' and `Object' are used so
231 frequently that they could be cached. */
233 void
234 append_gpp_mangled_name (const char *name, int len)
236 int encoded_len, needs_escapes;
237 char buf[6];
239 MANGLE_CXX_KEYWORDS (name, len);
241 encoded_len = unicode_mangling_length (name, len);
242 needs_escapes = encoded_len > 0;
244 sprintf (buf, "%d", (needs_escapes ? encoded_len : len));
245 obstack_grow (mangle_obstack, buf, strlen (buf));
247 if (needs_escapes)
248 append_unicode_mangled_name (name, len);
249 else
250 obstack_grow (mangle_obstack, name, len);
253 /* Assuming (NAME, LEN) is a Utf8-encoded string, emit the string
254 appropriately mangled (with Unicode escapes) to MANGLE_OBSTACK.
255 Characters needing an escape are encoded `__UNN_' to `__UNNNN_', in
256 which case `__U' will be mangled `__U_'. */
258 static void
259 append_unicode_mangled_name (const char *name, int len)
261 const unsigned char *ptr;
262 const unsigned char *limit = (const unsigned char *)name + len;
263 int uuU = 0;
264 for (ptr = (const unsigned char *) name; ptr < limit; )
266 int ch = UTF8_GET(ptr, limit);
268 if ((ISALNUM (ch) && ch != 'U') || ch == '$')
270 obstack_1grow (mangle_obstack, ch);
271 uuU = 0;
273 /* Everything else needs encoding */
274 else
276 char buf [9];
277 if (ch == '_' || ch == 'U')
279 /* Prepare to recognize __U */
280 if (ch == '_' && (uuU < 3))
282 uuU++;
283 obstack_1grow (mangle_obstack, ch);
285 /* We recognize __U that we wish to encode
286 __U_. Finish the encoding. */
287 else if (ch == 'U' && (uuU == 2))
289 uuU = 0;
290 obstack_grow (mangle_obstack, "U_", 2);
292 /* Otherwise, just reset uuU and emit the character we
293 have. */
294 else
296 uuU = 0;
297 obstack_1grow (mangle_obstack, ch);
299 continue;
301 sprintf (buf, "__U%x_", ch);
302 obstack_grow (mangle_obstack, buf, strlen (buf));
303 uuU = 0;
308 /* Assuming (NAME, LEN) is a Utf8-encoding string, calculate the
309 length of the string as mangled (a la g++) including Unicode
310 escapes. If no escapes are needed, return 0. */
312 static int
313 unicode_mangling_length (const char *name, int len)
315 const unsigned char *ptr;
316 const unsigned char *limit = (const unsigned char *)name + len;
317 int need_escapes = 0; /* Whether we need an escape or not */
318 int num_chars = 0; /* Number of characters in the mangled name */
319 int uuU = 0; /* Help us to find __U. 0: '_', 1: '__' */
320 for (ptr = (const unsigned char *) name; ptr < limit; )
322 int ch = UTF8_GET(ptr, limit);
324 if (ch < 0)
325 error ("internal error - invalid Utf8 name");
326 if ((ISALNUM (ch) && ch != 'U') || ch == '$')
328 num_chars++;
329 uuU = 0;
331 /* Everything else needs encoding */
332 else
334 int encoding_length = 2;
336 if (ch == '_' || ch == 'U')
338 /* It's always at least one character. */
339 num_chars++;
341 /* Prepare to recognize __U */
342 if (ch == '_' && (uuU < 3))
343 uuU++;
345 /* We recognize __U that we wish to encode __U_, we
346 count one more character. */
347 else if (ch == 'U' && (uuU == 2))
349 num_chars++;
350 need_escapes = 1;
351 uuU = 0;
353 /* Otherwise, just reset uuU */
354 else
355 uuU = 0;
357 continue;
360 if (ch > 0xff)
361 encoding_length++;
362 if (ch > 0xfff)
363 encoding_length++;
365 num_chars += (4 + encoding_length);
366 need_escapes = 1;
367 uuU = 0;
370 if (need_escapes)
371 return num_chars;
372 else
373 return 0;
376 #else
378 /* The assembler supports UTF8, we don't use escapes. Mangling is
379 simply <N>NAME. <N> is the number of UTF8 encoded characters that
380 are found in NAME. Note that `java', `lang' and `Object' are used
381 so frequently that they could be cached. */
383 void
384 append_gpp_mangled_name (const char *name, int len)
386 const unsigned char *ptr;
387 const unsigned char *limit;
388 int encoded_len;
389 char buf [6];
391 MANGLE_CXX_KEYWORDS (name, len);
393 limit = (const unsigned char *)name + len;
395 /* Compute the length of the string we wish to mangle. */
396 for (encoded_len = 0, ptr = (const unsigned char *) name;
397 ptr < limit; encoded_len++)
399 int ch = UTF8_GET(ptr, limit);
401 if (ch < 0)
402 error ("internal error - invalid Utf8 name");
405 sprintf (buf, "%d", encoded_len);
406 obstack_grow (mangle_obstack, buf, strlen (buf));
407 obstack_grow (mangle_obstack, name, len);
410 #endif /* HAVE_AS_UTF8 */