]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/java/mangle.c
jcf-path.c (jcf_path_init): Don't name variable 'try'.
[thirdparty/gcc.git] / gcc / java / mangle.c
CommitLineData
e04a16fb
AG
1/* Functions related to mangling class names for the GNU compiler
2 for the Java(TM) language.
f02a84d9 3 Copyright (C) 1998, 1999, 2001, 2002, 2003, 2006, 2007, 2008
43c6a96a 4 Free Software Foundation, Inc.
e04a16fb 5
f309ff0a 6This file is part of GCC.
e04a16fb 7
f309ff0a 8GCC is free software; you can redistribute it and/or modify
e04a16fb 9it under the terms of the GNU General Public License as published by
8328d52a 10the Free Software Foundation; either version 3, or (at your option)
e04a16fb
AG
11any later version.
12
f309ff0a 13GCC is distributed in the hope that it will be useful,
e04a16fb
AG
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
8328d52a
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>.
e04a16fb
AG
21
22Java and all Java-based marks are trademarks or registered trademarks
23of Sun Microsystems, Inc. in the United States and other countries.
24The Free Software Foundation is independent of Sun Microsystems, Inc. */
25
26/* Written by Per Bothner <bothner@cygnus.com> */
27
e04a16fb 28#include "config.h"
1f43f4b4 29#include "system.h"
4977bab6
ZW
30#include "coretypes.h"
31#include "tm.h"
e04a16fb 32#include "jcf.h"
4bcde32e
KG
33#include "tree.h"
34#include "java-tree.h"
e04a16fb 35#include "obstack.h"
d4476be2 36#include "toplev.h"
dc08e603 37#include "ggc.h"
6de33afa 38#include "langhooks-def.h"
dc08e603 39
6de33afa
RH
40static void mangle_class_field (tree);
41static void mangle_vtable (tree);
d2097937
KG
42static void mangle_field_decl (tree);
43static void mangle_method_decl (tree);
6de33afa 44static void mangle_local_cni_method_decl (tree);
dc08e603 45
d2097937
KG
46static void mangle_type (tree);
47static void mangle_pointer_type (tree);
48static void mangle_array_type (tree);
49static int mangle_record_type (tree, int);
dc08e603 50
d2097937
KG
51static int find_compression_pointer_match (tree);
52static int find_compression_array_match (tree);
53static int find_compression_record_match (tree, tree *);
54static int find_compression_array_template_match (tree);
dc08e603 55
d2097937
KG
56static void set_type_package_list (tree);
57static int entry_match_pointer_p (tree, int);
58static void emit_compression_string (int);
dc08e603 59
6de33afa 60static void init_mangling (void);
d2097937
KG
61static tree finish_mangling (void);
62static void compression_table_add (tree);
dc08e603 63
d2097937 64static void mangle_member_name (tree);
dc08e603 65
6de33afa 66static struct obstack mangle_obstack_1;
dc08e603 67struct obstack *mangle_obstack;
6de33afa 68
dc08e603
APB
69#define MANGLE_RAW_STRING(S) \
70 obstack_grow (mangle_obstack, (S), sizeof (S)-1)
71
bdc225df
RM
72/* atms: array template mangled string. */
73static GTY(()) tree atms;
74
97b8365c
TT
75static int
76utf8_cmp (const unsigned char *str, int length, const char *name)
77{
78 const unsigned char *limit = str + length;
79 int i;
80
81 for (i = 0; name[i]; ++i)
82 {
83 int ch = UTF8_GET (str, limit);
84 if (ch != name[i])
85 return ch - name[i];
86 }
87
88 return str == limit ? 0 : 1;
89}
90
91/* A sorted list of all C++ keywords. */
92static const char *const cxx_keywords[] =
93{
94 "_Complex",
95 "__alignof",
96 "__alignof__",
97 "__asm",
98 "__asm__",
99 "__attribute",
100 "__attribute__",
101 "__builtin_va_arg",
102 "__complex",
103 "__complex__",
104 "__const",
105 "__const__",
106 "__extension__",
107 "__imag",
108 "__imag__",
109 "__inline",
110 "__inline__",
111 "__label__",
112 "__null",
113 "__real",
114 "__real__",
115 "__restrict",
116 "__restrict__",
117 "__signed",
118 "__signed__",
119 "__typeof",
120 "__typeof__",
121 "__volatile",
122 "__volatile__",
123 "and",
124 "and_eq",
125 "asm",
126 "auto",
127 "bitand",
128 "bitor",
129 "bool",
130 "break",
131 "case",
132 "catch",
133 "char",
134 "class",
135 "compl",
136 "const",
137 "const_cast",
138 "continue",
139 "default",
140 "delete",
141 "do",
142 "double",
143 "dynamic_cast",
144 "else",
145 "enum",
146 "explicit",
147 "export",
148 "extern",
149 "false",
150 "float",
151 "for",
152 "friend",
153 "goto",
154 "if",
155 "inline",
156 "int",
157 "long",
158 "mutable",
159 "namespace",
160 "new",
161 "not",
162 "not_eq",
163 "operator",
164 "or",
165 "or_eq",
166 "private",
167 "protected",
168 "public",
169 "register",
170 "reinterpret_cast",
171 "return",
172 "short",
173 "signed",
174 "sizeof",
175 "static",
176 "static_cast",
177 "struct",
178 "switch",
179 "template",
180 "this",
181 "throw",
182 "true",
183 "try",
184 "typedef",
185 "typeid",
186 "typename",
187 "typeof",
188 "union",
189 "unsigned",
190 "using",
191 "virtual",
192 "void",
193 "volatile",
194 "wchar_t",
195 "while",
196 "xor",
197 "xor_eq"
198};
199
200/* Return true if NAME is a C++ keyword. */
201static int
202cxx_keyword_p (const char *name, int length)
203{
204 int last = ARRAY_SIZE (cxx_keywords);
205 int first = 0;
206 int mid = (last + first) / 2;
207 int old = -1;
208
209 for (mid = (last + first) / 2;
210 mid != old;
211 old = mid, mid = (last + first) / 2)
212 {
213 int kwl = strlen (cxx_keywords[mid]);
214 int min_length = kwl > length ? length : kwl;
215 int r = utf8_cmp ((const unsigned char *) name, min_length, cxx_keywords[mid]);
216
217 if (r == 0)
218 {
219 int i;
220 /* We've found a match if all the remaining characters are `$'. */
221 for (i = min_length; i < length && name[i] == '$'; ++i)
222 ;
223 if (i == length)
224 return 1;
225 r = 1;
226 }
227
228 if (r < 0)
229 last = mid;
230 else
231 first = mid;
232 }
233 return 0;
234}
235
dc08e603
APB
236/* This is the mangling interface: a decl, a class field (.class) and
237 the vtable. */
238
6de33afa
RH
239void
240java_mangle_decl (tree decl)
dc08e603 241{
6de33afa
RH
242 /* A copy of the check from the beginning of lhd_set_decl_assembler_name.
243 Only FUNCTION_DECLs and VAR_DECLs for variables with static storage
244 duration need a real DECL_ASSEMBLER_NAME. */
245 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
246 || (TREE_CODE (decl) == VAR_DECL
247 && (TREE_STATIC (decl)
248 || DECL_EXTERNAL (decl)
249 || TREE_PUBLIC (decl))));
250
251 /* Mangling only applies to class members. */
252 if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
dc08e603 253 {
6de33afa
RH
254 init_mangling ();
255 switch (TREE_CODE (decl))
256 {
257 case VAR_DECL:
258 if (DECL_LANG_SPECIFIC (decl))
259 {
260 if (DECL_CLASS_FIELD_P (decl))
261 {
621ae65d 262 mangle_class_field (decl);
6de33afa
RH
263 break;
264 }
265 else if (DECL_VTABLE_P (decl))
266 {
267 mangle_vtable (DECL_CONTEXT (decl));
268 break;
269 }
270 }
271 mangle_field_decl (decl);
272 break;
273
274 case FUNCTION_DECL:
275 if (DECL_LANG_SPECIFIC (decl) && DECL_LOCAL_CNI_METHOD_P (decl))
276 mangle_local_cni_method_decl (decl);
277 else
278 mangle_method_decl (decl);
279 break;
280
281 default:
282 gcc_unreachable ();
283 }
284 SET_DECL_ASSEMBLER_NAME (decl, finish_mangling ());
dc08e603 285 }
6de33afa
RH
286 else
287 lhd_set_decl_assembler_name (decl);
dc08e603
APB
288}
289
6de33afa
RH
290/* Beginning of the helper functions */
291
292static void
621ae65d 293mangle_class_field (tree decl)
dc08e603 294{
621ae65d 295 tree type = DECL_CONTEXT (decl);
551bf03c 296 mangle_record_type (type, /* for_pointer = */ 0);
621ae65d
AH
297 if (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE)
298 MANGLE_RAW_STRING ("6class$");
299 else
300 MANGLE_RAW_STRING ("7class$$");
dc08e603 301 obstack_1grow (mangle_obstack, 'E');
dc08e603
APB
302}
303
6de33afa
RH
304static void
305mangle_vtable (tree type)
dc08e603 306{
dc08e603 307 MANGLE_RAW_STRING ("TV");
551bf03c 308 mangle_record_type (type, /* for_pointer = */ 0);
dc08e603 309 obstack_1grow (mangle_obstack, 'E');
dc08e603
APB
310}
311
dc08e603
APB
312/* This mangles a field decl */
313
314static void
0a2f0c54 315mangle_field_decl (tree decl)
dc08e603 316{
dc08e603 317 /* Mangle the name of the this the field belongs to */
551bf03c 318 mangle_record_type (DECL_CONTEXT (decl), /* for_pointer = */ 0);
dc08e603
APB
319
320 /* Mangle the name of the field */
1b43b6be 321 mangle_member_name (DECL_NAME (decl));
dc08e603
APB
322
323 /* Terminate the mangled name */
324 obstack_1grow (mangle_obstack, 'E');
dc08e603
APB
325}
326
327/* This mangles a method decl, first mangling its name and then all
328 its arguments. */
329
330static void
0a2f0c54 331mangle_method_decl (tree mdecl)
dc08e603
APB
332{
333 tree method_name = DECL_NAME (mdecl);
334 tree arglist;
dc08e603
APB
335
336 /* Mangle the name of the type that contains mdecl */
551bf03c 337 mangle_record_type (DECL_CONTEXT (mdecl), /* for_pointer = */ 0);
dc08e603 338
2c5187c5 339 /* Mangle the function name. There are two cases:
dc08e603
APB
340 - mdecl is a constructor, use `C1' for its name, (denotes a
341 complete object constructor.)
342 - mdecl is not a constructor, standard mangling is performed.
343 We terminate the mangled function name with a `E'. */
344 if (ID_INIT_P (method_name))
2c5187c5 345 obstack_grow (mangle_obstack, "C1", 2);
dc08e603 346 else
1b43b6be 347 mangle_member_name (method_name);
dc08e603
APB
348 obstack_1grow (mangle_obstack, 'E');
349
350 /* We mangled type.methodName. Now onto the arguments. */
351 arglist = TYPE_ARG_TYPES (TREE_TYPE (mdecl));
352 if (TREE_CODE (TREE_TYPE (mdecl)) == METHOD_TYPE)
353 arglist = TREE_CHAIN (arglist);
354
92aed1cb
TL
355 /* Output literal 'J' and mangle the return type IF not a
356 constructor. */
357 if (!ID_INIT_P (method_name))
358 {
359 obstack_1grow (mangle_obstack, 'J');
360 mangle_type(TREE_TYPE(TREE_TYPE(mdecl)));
361 }
362
dc08e603
APB
363 /* No arguments is easy. We shortcut it. */
364 if (arglist == end_params_node)
365 obstack_1grow (mangle_obstack, 'v');
366 else
367 {
368 tree arg;
369 for (arg = arglist; arg != end_params_node; arg = TREE_CHAIN (arg))
370 mangle_type (TREE_VALUE (arg));
371 }
dc08e603
APB
372}
373
6de33afa
RH
374/* This mangles a CNI method for a local class. If the target supports
375 hidden aliases, then G++ will have generated one for us. It is the
376 responsibility of java_mark_class_local to check target support, since
377 we need to set DECL_VISIBILITY (or not) much earlier. */
378
379static void
380mangle_local_cni_method_decl (tree decl)
381{
382 MANGLE_RAW_STRING ("GA");
383 mangle_method_decl (decl);
384}
385
dc08e603 386/* This mangles a member name, like a function name or a field
ee142fe7 387 name. Handle cases were `name' is a C++ keyword. Return a nonzero
dc08e603
APB
388 value if unicode encoding was required. */
389
1b43b6be 390static void
0a2f0c54 391mangle_member_name (tree name)
dc08e603 392{
1b43b6be
APB
393 append_gpp_mangled_name (IDENTIFIER_POINTER (name),
394 IDENTIFIER_LENGTH (name));
dc08e603 395
621ae65d 396 /* If NAME happens to be a C++ keyword, add `$'. */
dc08e603 397 if (cxx_keyword_p (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name)))
de4984af 398 obstack_1grow (mangle_obstack, '$');
e04a16fb
AG
399}
400
dc08e603 401/* Append the mangled name of TYPE onto OBSTACK. */
e04a16fb 402
dc08e603 403static void
0a2f0c54 404mangle_type (tree type)
dc08e603
APB
405{
406 switch (TREE_CODE (type))
407 {
408 char code;
409 case BOOLEAN_TYPE: code = 'b'; goto primitive;
dc08e603
APB
410 case VOID_TYPE: code = 'v'; goto primitive;
411 case INTEGER_TYPE:
5460aa9c
RS
412 if (type == char_type_node || type == promoted_char_type_node)
413 {
414 code = 'w';
415 goto primitive;
416 }
dc08e603
APB
417 /* Get the original type instead of the arguments promoted type.
418 Avoid symbol name clashes. Should call a function to do that.
419 FIXME. */
420 if (type == promoted_short_type_node)
421 type = short_type_node;
422 if (type == promoted_byte_type_node)
423 type = byte_type_node;
424 switch (TYPE_PRECISION (type))
425 {
426 case 8: code = 'c'; goto primitive;
427 case 16: code = 's'; goto primitive;
428 case 32: code = 'i'; goto primitive;
429 case 64: code = 'x'; goto primitive;
430 default: goto bad_type;
431 }
432 primitive:
433 obstack_1grow (mangle_obstack, code);
434 break;
435
436 case REAL_TYPE:
437 switch (TYPE_PRECISION (type))
438 {
439 case 32: code = 'f'; goto primitive;
440 case 64: code = 'd'; goto primitive;
441 default: goto bad_type;
442 }
443 case POINTER_TYPE:
444 if (TYPE_ARRAY_P (TREE_TYPE (type)))
445 mangle_array_type (type);
446 else
447 mangle_pointer_type (type);
448 break;
449 bad_type:
450 default:
ab184b2a 451 gcc_unreachable ();
dc08e603
APB
452 }
453}
454
455/* The compression table is a vector that keeps track of things we've
456 already seen, so they can be reused. For example, java.lang.Object
98f705b9 457 would generate three entries: two package names and a type. If
dc08e603 458 java.lang.String is presented next, the java.lang will be matched
bdc225df 459 against the first two entries (and kept for compression as S0_), and
dc08e603
APB
460 type String would be added to the table. See mangle_record_type.
461 COMPRESSION_NEXT is the index to the location of the next insertion
462 of an element. */
463
e2500fed 464static GTY(()) tree compression_table;
dc08e603
APB
465static int compression_next;
466
467/* Find a POINTER_TYPE in the compression table. Use a special
468 function to match pointer entries and start from the end */
469
470static int
0a2f0c54 471find_compression_pointer_match (tree type)
dc08e603
APB
472{
473 int i;
474
475 for (i = compression_next-1; i >= 0; i--)
476 if (entry_match_pointer_p (type, i))
477 return i;
478 return -1;
479}
480
481/* Already recorder arrays are handled like pointer as they're always
482 associated with it. */
483
484static int
0a2f0c54 485find_compression_array_match (tree type)
dc08e603
APB
486{
487 return find_compression_pointer_match (type);
488}
489
490/* Match the table of type against STRING. */
491
492static int
0a2f0c54 493find_compression_array_template_match (tree string)
dc08e603
APB
494{
495 int i;
496 for (i = 0; i < compression_next; i++)
497 if (TREE_VEC_ELT (compression_table, i) == string)
498 return i;
499 return -1;
500}
501
502/* We go through the compression table and try to find a complete or
503 partial match. The function returns the compression table entry
634661fe 504 that (eventually partially) matches TYPE. *NEXT_CURRENT can be set
dc08e603
APB
505 to the rest of TYPE to be mangled. */
506
507static int
0a2f0c54 508find_compression_record_match (tree type, tree *next_current)
e04a16fb 509{
ed2506a4 510 int i, match = -1;
962584ea 511 tree current, saved_current = NULL_TREE;
e04a16fb 512
ed2506a4
BM
513 current = TYPE_PACKAGE_LIST (type);
514
515 for (i = 0; i < compression_next; i++)
e04a16fb 516 {
ed2506a4
BM
517 tree compression_entry = TREE_VEC_ELT (compression_table, i);
518 if (current && compression_entry == TREE_PURPOSE (current))
519 {
520 match = i;
521 saved_current = current;
522 current = TREE_CHAIN (current);
523 }
524 else
525 /* We don't want to match an element that appears in the middle
526 of a package name, so skip forward to the next complete type name.
527 IDENTIFIER_NODEs (except for a "6JArray") are partial package
528 names while RECORD_TYPEs represent complete type names. */
529 while (i < compression_next
530 && TREE_CODE (compression_entry) == IDENTIFIER_NODE
531 && compression_entry != atms)
532 compression_entry = TREE_VEC_ELT (compression_table, ++i);
dc08e603
APB
533 }
534
535 if (!next_current)
536 return match;
537
538 /* If we have a match, set next_current to the item next to the last
539 matched value. */
540 if (match >= 0)
541 *next_current = TREE_CHAIN (saved_current);
542 /* We had no match: we'll have to start from the beginning. */
543 if (match < 0)
544 *next_current = TYPE_PACKAGE_LIST (type);
545
546 return match;
547}
548
ee142fe7 549/* Mangle a record type. If a nonzero value is returned, it means
dc08e603 550 that a 'N' was emitted (so that a matching 'E' can be emitted if
551bf03c
BM
551 necessary.) FOR_POINTER indicates that this element is for a pointer
552 symbol, meaning it was preceded by a 'P'. */
dc08e603
APB
553
554static int
0a2f0c54 555mangle_record_type (tree type, int for_pointer)
dc08e603
APB
556{
557 tree current;
558 int match;
559 int nadded_p = 0;
551bf03c
BM
560 int qualified;
561
562 /* Does this name have a package qualifier? */
563 qualified = QUALIFIED_P (DECL_NAME (TYPE_NAME (type)));
dc08e603
APB
564
565#define ADD_N() \
566 do { obstack_1grow (mangle_obstack, 'N'); nadded_p = 1; } while (0)
567
ab184b2a 568 gcc_assert (TREE_CODE (type) == RECORD_TYPE);
dc08e603
APB
569
570 if (!TYPE_PACKAGE_LIST (type))
571 set_type_package_list (type);
572
573 match = find_compression_record_match (type, &current);
574 if (match >= 0)
575 {
576 /* If we had a pointer, and there's more, we need to emit
551bf03c
BM
577 'N' after 'P' (for_pointer tells us we already emitted it.) */
578 if (for_pointer && current)
dc08e603
APB
579 ADD_N();
580 emit_compression_string (match);
e04a16fb 581 }
dc08e603 582 while (current)
e04a16fb 583 {
dc08e603
APB
584 /* Add the new type to the table */
585 compression_table_add (TREE_PURPOSE (current));
551bf03c
BM
586 /* Add 'N' if we never got a chance to, but only if we have a qualified
587 name. For non-pointer elements, the name is always qualified. */
588 if ((qualified || !for_pointer) && !nadded_p)
dc08e603
APB
589 ADD_N();
590 /* Use the bare type name for the mangle. */
591 append_gpp_mangled_name (IDENTIFIER_POINTER (TREE_VALUE (current)),
592 IDENTIFIER_LENGTH (TREE_VALUE (current)));
593 current = TREE_CHAIN (current);
594 }
595 return nadded_p;
596#undef ADD_N
597}
598
599/* Mangle a pointer type. There are two cases: the pointer is already
634661fe 600 in the compression table: the compression is emitted sans 'P'
dc08e603
APB
601 indicator. Otherwise, a 'P' is emitted and, depending on the type,
602 a partial compression or/plus the rest of the mangling. */
603
604static void
0a2f0c54 605mangle_pointer_type (tree type)
dc08e603
APB
606{
607 int match;
608 tree pointer_type;
609
610 /* Search for the type already in the compression table */
611 if ((match = find_compression_pointer_match (type)) >= 0)
612 {
613 emit_compression_string (match);
614 return;
e04a16fb 615 }
dc08e603
APB
616
617 /* This didn't work. We start by mangling the pointed-to type */
618 pointer_type = type;
619 type = TREE_TYPE (type);
ab184b2a 620 gcc_assert (TREE_CODE (type) == RECORD_TYPE);
dc08e603
APB
621
622 obstack_1grow (mangle_obstack, 'P');
623 if (mangle_record_type (type, /* for_pointer = */ 1))
624 obstack_1grow (mangle_obstack, 'E');
625
626 /* Don't forget to insert the pointer type in the table */
627 compression_table_add (pointer_type);
628}
629
630/* Mangle an array type. Search for an easy solution first, then go
631 through the process of finding out whether the bare array type or even
bdc225df 632 the template indicator were already used and compressed appropriately.
dc08e603
APB
633 It handles pointers. */
634
635static void
0a2f0c54 636mangle_array_type (tree p_type)
dc08e603 637{
dc08e603
APB
638 tree type, elt_type;
639 int match;
640
641 type = TREE_TYPE (p_type);
ab184b2a 642 gcc_assert (type);
400500c4 643
dc08e603
APB
644 elt_type = TYPE_ARRAY_ELEMENT (type);
645
646 /* We cache a bit of the Jarray <> mangle. */
647 if (!atms)
648 {
649 atms = get_identifier ("6JArray");
dc08e603
APB
650 }
651
bdc225df 652 /* Maybe we have what we're looking for in the compression table. */
dc08e603
APB
653 if ((match = find_compression_array_match (p_type)) >= 0)
654 {
655 emit_compression_string (match);
656 return;
657 }
658
659 /* We know for a fact that all arrays are pointers */
660 obstack_1grow (mangle_obstack, 'P');
661 /* Maybe we already have a Jarray<t> somewhere. PSx_ will be enough. */
662 if ((match = find_compression_record_match (type, NULL)) > 0)
663 {
664 emit_compression_string (match);
665 return;
666 }
667
668 /* Maybe we already have just JArray somewhere */
669 if ((match = find_compression_array_template_match (atms)) > 0)
670 emit_compression_string (match);
671 else
e04a16fb 672 {
dc08e603
APB
673 /* Start the template mangled name */
674 obstack_grow (mangle_obstack,
675 IDENTIFIER_POINTER (atms), IDENTIFIER_LENGTH (atms));
676 /* Insert in the compression table */
677 compression_table_add (atms);
678 }
679
680 /* Mangle Jarray <elt_type> */
681 obstack_1grow (mangle_obstack, 'I');
682 mangle_type (elt_type);
683 obstack_1grow (mangle_obstack, 'E');
684
685 /* Add `Jarray <elt_type>' and `Jarray <elt_type> *' to the table */
686 compression_table_add (type);
687 compression_table_add (p_type);
688}
689
634661fe 690/* Write a substitution string for entry I. Substitution string starts a
67264b4f 691 -1 (encoded S_.) The base is 36, and the code shamelessly taken from
dc08e603
APB
692 cp/mangle.c. */
693
694static void
695emit_compression_string (int i)
696{
697 i -= 1; /* Adjust */
698 obstack_1grow (mangle_obstack, 'S');
699 if (i >= 0)
700 {
701 static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
702 unsigned HOST_WIDE_INT n;
703 unsigned HOST_WIDE_INT m=1;
704 /* How many digits for I in base 36? */
705 for (n = i; n >= 36; n /= 36, m *=36);
706 /* Write the digits out */
707 while (m > 0)
e04a16fb 708 {
dc08e603
APB
709 int digit = i / m;
710 obstack_1grow (mangle_obstack, digits [digit]);
711 i -= digit * m;
712 m /= 36;
713 }
714 }
715 obstack_1grow (mangle_obstack, '_');
716}
717
718/* If search the compression table at index I for a pointer type
719 equivalent to TYPE (meaning that after all the indirection, which
720 might all be unique, we find the same RECORD_TYPE.) */
721
722static int
0a2f0c54 723entry_match_pointer_p (tree type, int i)
dc08e603
APB
724{
725 tree t = TREE_VEC_ELT (compression_table, i);
726
727 while (TREE_CODE (type) == POINTER_TYPE
728 && TREE_CODE (t) == POINTER_TYPE)
729 {
730 t = TREE_TYPE (t);
731 type = TREE_TYPE (type);
732 }
733 return (TREE_CODE (type) == RECORD_TYPE
734 && TREE_CODE (t) == RECORD_TYPE
735 && t == type);
736}
737
738/* Go through all qualification of type and build a list of list node
739 elements containings as a purpose what should be used for a match and
740 inserted in the compression table; and as it value the raw name of the
741 part. The result is stored in TYPE_PACKAGE_LIST to be reused. */
742
743static void
0a2f0c54 744set_type_package_list (tree type)
dc08e603
APB
745{
746 int i;
747 const char *type_string = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
0b740634 748 const char *ptr;
dc08e603
APB
749 int qualifications;
750 tree list = NULL_TREE, elt;
751
0b740634 752 for (ptr = type_string, qualifications = 0; *ptr; ptr++)
dc08e603
APB
753 if (*ptr == '.')
754 qualifications += 1;
755
0b740634 756 for (ptr = type_string, i = 0; i < qualifications; ptr++)
dc08e603
APB
757 {
758 if (ptr [0] == '.')
759 {
0b740634
KG
760 tree const identifier
761 = get_identifier_with_length (type_string, ptr - type_string);
762
dc08e603
APB
763 elt = build_tree_list (identifier, identifier);
764 TREE_CHAIN (elt) = list;
765 list = elt;
766 type_string = ptr+1;
767 i += 1;
e04a16fb
AG
768 }
769 }
dc08e603
APB
770
771 elt = build_tree_list (type, get_identifier (type_string));
772 TREE_CHAIN (elt) = list;
773 list = elt;
774 TYPE_PACKAGE_LIST (type) = nreverse (list);
775}
776
777/* Add TYPE as the last element of the compression table. Resize the
778 compression table if necessary. */
779
780static void
0a2f0c54 781compression_table_add (tree type)
dc08e603
APB
782{
783 if (compression_next == TREE_VEC_LENGTH (compression_table))
784 {
f02a84d9 785 tree new_table = make_tree_vec (2*compression_next);
dc08e603
APB
786 int i;
787
788 for (i = 0; i < compression_next; i++)
f02a84d9 789 TREE_VEC_ELT (new_table, i) = TREE_VEC_ELT (compression_table, i);
dc08e603 790
f02a84d9 791 compression_table = new_table;
dc08e603
APB
792 }
793 TREE_VEC_ELT (compression_table, compression_next++) = type;
794}
795
3e603aef
DD
796/* Mangle an embedded resource file name. "_ZGr" is the prefix. A
797 '_' is prepended to the name so that names starting with a digit
798 can be demangled. The length and then the resulting name itself
799 are appended while escaping '$', '.', and '/' to: "$$", "$_", and
800 "$S". */
801
802tree
803java_mangle_resource_name (const char *name)
804{
805 int len = strlen (name);
806 char *buf = (char *) alloca (2 * len + 1);
807 char *pos;
808 const unsigned char *w1 = (const unsigned char *) name;
809 const unsigned char *w2;
810 const unsigned char *limit = w1 + len;
811
812 pos = buf;
813
814 init_mangling ();
815 MANGLE_RAW_STRING ("Gr");
816
817 *pos++ = '_';
818 while (w1 < limit)
819 {
820 int ch;
821 w2 = w1;
822 ch = UTF8_GET (w1, limit);
823 gcc_assert (ch > 0);
824 switch (ch)
825 {
826 case '$':
827 *pos++ = '$';
828 *pos++ = '$';
829 break;
830 case '.':
831 *pos++ = '$';
832 *pos++ = '_';
833 break;
834 case '/':
835 *pos++ = '$';
836 *pos++ = 'S';
837 break;
838 default:
839 memcpy (pos, w2, w1 - w2);
840 pos += w1 - w2;
841 break;
842 }
843 }
844 append_gpp_mangled_name (buf, pos - buf);
845
846 return finish_mangling ();
847}
848
dc08e603
APB
849/* Mangling initialization routine. */
850
851static void
6de33afa 852init_mangling (void)
dc08e603 853{
6de33afa
RH
854 if (!mangle_obstack)
855 {
856 mangle_obstack = &mangle_obstack_1;
857 gcc_obstack_init (mangle_obstack);
858 }
859
860 gcc_assert (compression_table == NULL);
861 compression_table = make_tree_vec (10);
dc08e603
APB
862
863 /* Mangled name are to be suffixed */
6de33afa 864 MANGLE_RAW_STRING ("_Z");
dc08e603
APB
865}
866
867/* Mangling finalization routine. The mangled name is returned as a
868 IDENTIFIER_NODE. */
869
870static tree
0a2f0c54 871finish_mangling (void)
dc08e603
APB
872{
873 tree result;
874
6de33afa 875 gcc_assert (compression_table);
dc08e603 876
dc08e603
APB
877 compression_table = NULL_TREE;
878 compression_next = 0;
879 obstack_1grow (mangle_obstack, '\0');
880 result = get_identifier (obstack_base (mangle_obstack));
881 obstack_free (mangle_obstack, obstack_base (mangle_obstack));
6de33afa 882
dc08e603 883 return result;
e04a16fb 884}
e2500fed
GK
885
886#include "gt-java-mangle.h"