* config/pa/linux-atomic.c (__kernel_cmpxchg): Reorder arguments to
[official-gcc.git] / gcc / java / mangle_name.c
blob050f5da97278167706672d257969c869a98f1e09
1 /* Shared functions related to mangling names for the GNU compiler
2 for the Java(TM) language.
3 Copyright (C) 2001-2015 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 "jcf.h"
31 #include "alias.h"
32 #include "symtab.h"
33 #include "options.h"
34 #include "tree.h"
35 #include "java-tree.h"
36 #include "obstack.h"
37 #include "diagnostic-core.h"
39 static void append_unicode_mangled_name (const char *, int);
40 #ifndef HAVE_AS_UTF8
41 static int unicode_mangling_length (const char *, int);
42 #endif
44 extern struct obstack *mangle_obstack;
46 static int
47 utf8_cmp (const unsigned char *str, int length, const char *name)
49 const unsigned char *limit = str + length;
50 int i;
52 for (i = 0; name[i]; ++i)
54 int ch = UTF8_GET (str, limit);
55 if (ch != name[i])
56 return ch - name[i];
59 return str == limit ? 0 : 1;
62 /* A sorted list of all C++ keywords. If you change this, be sure
63 also to change the list in
64 libjava/classpath/tools/gnu/classpath/tools/javah/Keywords.java. */
65 static const char *const cxx_keywords[] =
67 "_Complex",
68 "__alignof",
69 "__alignof__",
70 "__asm",
71 "__asm__",
72 "__attribute",
73 "__attribute__",
74 "__builtin_va_arg",
75 "__complex",
76 "__complex__",
77 "__const",
78 "__const__",
79 "__extension__",
80 "__imag",
81 "__imag__",
82 "__inline",
83 "__inline__",
84 "__label__",
85 "__null",
86 "__real",
87 "__real__",
88 "__restrict",
89 "__restrict__",
90 "__signed",
91 "__signed__",
92 "__typeof",
93 "__typeof__",
94 "__volatile",
95 "__volatile__",
96 "and",
97 "and_eq",
98 "asm",
99 "auto",
100 "bitand",
101 "bitor",
102 "bool",
103 "break",
104 "case",
105 "catch",
106 "char",
107 "class",
108 "compl",
109 "const",
110 "const_cast",
111 "continue",
112 "default",
113 "delete",
114 "do",
115 "double",
116 "dynamic_cast",
117 "else",
118 "enum",
119 "explicit",
120 "export",
121 "extern",
122 "false",
123 "float",
124 "for",
125 "friend",
126 "goto",
127 "if",
128 "inline",
129 "int",
130 "long",
131 "mutable",
132 "namespace",
133 "new",
134 "not",
135 "not_eq",
136 "operator",
137 "or",
138 "or_eq",
139 "private",
140 "protected",
141 "public",
142 "register",
143 "reinterpret_cast",
144 "return",
145 "short",
146 "signed",
147 "sizeof",
148 "static",
149 "static_cast",
150 "struct",
151 "switch",
152 "template",
153 "this",
154 "throw",
155 "true",
156 "try",
157 "typedef",
158 "typeid",
159 "typename",
160 "typeof",
161 "union",
162 "unsigned",
163 "using",
164 "virtual",
165 "void",
166 "volatile",
167 "wchar_t",
168 "while",
169 "xor",
170 "xor_eq"
173 /* Return true if NAME is a C++ keyword. */
175 cxx_keyword_p (const char *name, int length)
177 int last = ARRAY_SIZE (cxx_keywords);
178 int first = 0;
179 int mid = (last + first) / 2;
180 int old = -1;
182 for (mid = (last + first) / 2;
183 mid != old;
184 old = mid, mid = (last + first) / 2)
186 int kwl = strlen (cxx_keywords[mid]);
187 int min_length = kwl > length ? length : kwl;
188 int r = utf8_cmp ((const unsigned char *) name, min_length, cxx_keywords[mid]);
190 if (r == 0)
192 int i;
193 /* We've found a match if all the remaining characters are `$'. */
194 for (i = min_length; i < length && name[i] == '$'; ++i)
196 if (i == length)
197 return 1;
198 r = 1;
201 if (r < 0)
202 last = mid;
203 else
204 first = mid;
206 return 0;
209 /* If NAME happens to be a C++ keyword, add `$'. */
210 #define MANGLE_CXX_KEYWORDS(NAME, LEN) \
211 do \
213 if (cxx_keyword_p ((NAME), (LEN))) \
215 char *tmp_buf = (char *)alloca ((LEN)+1); \
216 memcpy (tmp_buf, (NAME), (LEN)); \
217 tmp_buf[LEN]= '$'; \
218 (NAME) = tmp_buf; \
219 (LEN)++; \
222 while (0)
225 /* If the assembler doesn't support UTF8 in symbol names, some
226 characters might need to be escaped. */
228 #ifndef HAVE_AS_UTF8
230 /* Assuming (NAME, LEN) is a Utf8-encoding string, emit the string
231 appropriately mangled (with Unicode escapes if needed) to
232 MANGLE_OBSTACK. Note that `java', `lang' and `Object' are used so
233 frequently that they could be cached. */
235 void
236 append_gpp_mangled_name (const char *name, int len)
238 int encoded_len, needs_escapes;
239 char buf[6];
241 MANGLE_CXX_KEYWORDS (name, len);
243 encoded_len = unicode_mangling_length (name, len);
244 needs_escapes = encoded_len > 0;
246 sprintf (buf, "%d", (needs_escapes ? encoded_len : len));
247 obstack_grow (mangle_obstack, buf, strlen (buf));
249 if (needs_escapes)
250 append_unicode_mangled_name (name, len);
251 else
252 obstack_grow (mangle_obstack, name, len);
255 /* Assuming (NAME, LEN) is a Utf8-encoded string, emit the string
256 appropriately mangled (with Unicode escapes) to MANGLE_OBSTACK.
257 Characters needing an escape are encoded `__UNN_' to `__UNNNN_', in
258 which case `__U' will be mangled `__U_'. */
260 static void
261 append_unicode_mangled_name (const char *name, int len)
263 const unsigned char *ptr;
264 const unsigned char *limit = (const unsigned char *)name + len;
265 int uuU = 0;
266 for (ptr = (const unsigned char *) name; ptr < limit; )
268 int ch = UTF8_GET(ptr, limit);
270 if ((ISALNUM (ch) && ch != 'U') || ch == '$')
272 obstack_1grow (mangle_obstack, ch);
273 uuU = 0;
275 /* Everything else needs encoding */
276 else
278 char buf [9];
279 if (ch == '_' || ch == 'U')
281 /* Prepare to recognize __U */
282 if (ch == '_' && (uuU < 3))
284 uuU++;
285 obstack_1grow (mangle_obstack, ch);
287 /* We recognize __U that we wish to encode
288 __U_. Finish the encoding. */
289 else if (ch == 'U' && (uuU == 2))
291 uuU = 0;
292 obstack_grow (mangle_obstack, "U_", 2);
294 /* Otherwise, just reset uuU and emit the character we
295 have. */
296 else
298 uuU = 0;
299 obstack_1grow (mangle_obstack, ch);
301 continue;
303 sprintf (buf, "__U%x_", ch);
304 obstack_grow (mangle_obstack, buf, strlen (buf));
305 uuU = 0;
310 /* Assuming (NAME, LEN) is a Utf8-encoding string, calculate the
311 length of the string as mangled (a la g++) including Unicode
312 escapes. If no escapes are needed, return 0. */
314 static int
315 unicode_mangling_length (const char *name, int len)
317 const unsigned char *ptr;
318 const unsigned char *limit = (const unsigned char *)name + len;
319 int need_escapes = 0; /* Whether we need an escape or not */
320 int num_chars = 0; /* Number of characters in the mangled name */
321 int uuU = 0; /* Help us to find __U. 0: '_', 1: '__' */
322 for (ptr = (const unsigned char *) name; ptr < limit; )
324 int ch = UTF8_GET(ptr, limit);
326 if (ch < 0)
327 error ("internal error - invalid Utf8 name");
328 if ((ISALNUM (ch) && ch != 'U') || ch == '$')
330 num_chars++;
331 uuU = 0;
333 /* Everything else needs encoding */
334 else
336 int encoding_length = 2;
338 if (ch == '_' || ch == 'U')
340 /* It's always at least one character. */
341 num_chars++;
343 /* Prepare to recognize __U */
344 if (ch == '_' && (uuU < 3))
345 uuU++;
347 /* We recognize __U that we wish to encode __U_, we
348 count one more character. */
349 else if (ch == 'U' && (uuU == 2))
351 num_chars++;
352 need_escapes = 1;
353 uuU = 0;
355 /* Otherwise, just reset uuU */
356 else
357 uuU = 0;
359 continue;
362 if (ch > 0xff)
363 encoding_length++;
364 if (ch > 0xfff)
365 encoding_length++;
367 num_chars += (4 + encoding_length);
368 need_escapes = 1;
369 uuU = 0;
372 if (need_escapes)
373 return num_chars;
374 else
375 return 0;
378 #else
380 /* The assembler supports UTF8, we don't use escapes. Mangling is
381 simply <N>NAME. <N> is the number of UTF8 encoded characters that
382 are found in NAME. Note that `java', `lang' and `Object' are used
383 so frequently that they could be cached. */
385 void
386 append_gpp_mangled_name (const char *name, int len)
388 const unsigned char *ptr;
389 const unsigned char *limit;
390 int encoded_len;
391 char buf [6];
393 MANGLE_CXX_KEYWORDS (name, len);
395 limit = (const unsigned char *)name + len;
397 /* Compute the length of the string we wish to mangle. */
398 for (encoded_len = 0, ptr = (const unsigned char *) name;
399 ptr < limit; encoded_len++)
401 int ch = UTF8_GET(ptr, limit);
403 if (ch < 0)
404 error ("internal error - invalid Utf8 name");
407 sprintf (buf, "%d", encoded_len);
408 obstack_grow (mangle_obstack, buf, strlen (buf));
409 obstack_grow (mangle_obstack, name, len);
412 #endif /* HAVE_AS_UTF8 */