2008-05-20 Kai Tietz <kai.tietz@onevision.com>
[official-gcc.git] / gcc / java / mangle.c
blob2e89a30f9929add01ccb8826baeb69718c0e83cb
1 /* Functions related to mangling class names for the GNU compiler
2 for the Java(TM) language.
3 Copyright (C) 1998, 1999, 2001, 2002, 2003, 2006, 2007
4 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>.
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 "coretypes.h"
31 #include "tm.h"
32 #include "jcf.h"
33 #include "tree.h"
34 #include "java-tree.h"
35 #include "obstack.h"
36 #include "toplev.h"
37 #include "ggc.h"
38 #include "langhooks-def.h"
40 static void mangle_class_field (tree);
41 static void mangle_vtable (tree);
42 static void mangle_field_decl (tree);
43 static void mangle_method_decl (tree);
44 static void mangle_local_cni_method_decl (tree);
46 static void mangle_type (tree);
47 static void mangle_pointer_type (tree);
48 static void mangle_array_type (tree);
49 static int mangle_record_type (tree, int);
51 static int find_compression_pointer_match (tree);
52 static int find_compression_array_match (tree);
53 static int find_compression_record_match (tree, tree *);
54 static int find_compression_array_template_match (tree);
56 static void set_type_package_list (tree);
57 static int entry_match_pointer_p (tree, int);
58 static void emit_compression_string (int);
60 static void init_mangling (void);
61 static tree finish_mangling (void);
62 static void compression_table_add (tree);
64 static void mangle_member_name (tree);
66 static struct obstack mangle_obstack_1;
67 struct obstack *mangle_obstack;
69 #define MANGLE_RAW_STRING(S) \
70 obstack_grow (mangle_obstack, (S), sizeof (S)-1)
72 /* atms: array template mangled string. */
73 static GTY(()) tree atms;
75 static int
76 utf8_cmp (const unsigned char *str, int length, const char *name)
78 const unsigned char *limit = str + length;
79 int i;
81 for (i = 0; name[i]; ++i)
83 int ch = UTF8_GET (str, limit);
84 if (ch != name[i])
85 return ch - name[i];
88 return str == limit ? 0 : 1;
91 /* A sorted list of all C++ keywords. */
92 static const char *const cxx_keywords[] =
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"
200 /* Return true if NAME is a C++ keyword. */
201 static int
202 cxx_keyword_p (const char *name, int length)
204 int last = ARRAY_SIZE (cxx_keywords);
205 int first = 0;
206 int mid = (last + first) / 2;
207 int old = -1;
209 for (mid = (last + first) / 2;
210 mid != old;
211 old = mid, mid = (last + first) / 2)
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]);
217 if (r == 0)
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)
223 if (i == length)
224 return 1;
225 r = 1;
228 if (r < 0)
229 last = mid;
230 else
231 first = mid;
233 return 0;
236 /* This is the mangling interface: a decl, a class field (.class) and
237 the vtable. */
239 void
240 java_mangle_decl (tree decl)
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))));
251 /* Mangling only applies to class members. */
252 if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
254 init_mangling ();
255 switch (TREE_CODE (decl))
257 case VAR_DECL:
258 if (DECL_LANG_SPECIFIC (decl))
260 if (DECL_CLASS_FIELD_P (decl))
262 mangle_class_field (decl);
263 break;
265 else if (DECL_VTABLE_P (decl))
267 mangle_vtable (DECL_CONTEXT (decl));
268 break;
271 mangle_field_decl (decl);
272 break;
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;
281 default:
282 gcc_unreachable ();
284 SET_DECL_ASSEMBLER_NAME (decl, finish_mangling ());
286 else
287 lhd_set_decl_assembler_name (decl);
290 /* Beginning of the helper functions */
292 static void
293 mangle_class_field (tree decl)
295 tree type = DECL_CONTEXT (decl);
296 mangle_record_type (type, /* for_pointer = */ 0);
297 if (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE)
298 MANGLE_RAW_STRING ("6class$");
299 else
300 MANGLE_RAW_STRING ("7class$$");
301 obstack_1grow (mangle_obstack, 'E');
304 static void
305 mangle_vtable (tree type)
307 MANGLE_RAW_STRING ("TV");
308 mangle_record_type (type, /* for_pointer = */ 0);
309 obstack_1grow (mangle_obstack, 'E');
312 /* This mangles a field decl */
314 static void
315 mangle_field_decl (tree decl)
317 /* Mangle the name of the this the field belongs to */
318 mangle_record_type (DECL_CONTEXT (decl), /* for_pointer = */ 0);
320 /* Mangle the name of the field */
321 mangle_member_name (DECL_NAME (decl));
323 /* Terminate the mangled name */
324 obstack_1grow (mangle_obstack, 'E');
327 /* This mangles a method decl, first mangling its name and then all
328 its arguments. */
330 static void
331 mangle_method_decl (tree mdecl)
333 tree method_name = DECL_NAME (mdecl);
334 tree arglist;
336 /* Mangle the name of the type that contains mdecl */
337 mangle_record_type (DECL_CONTEXT (mdecl), /* for_pointer = */ 0);
339 /* Mangle the function name. There are two cases:
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))
345 obstack_grow (mangle_obstack, "C1", 2);
346 else
347 mangle_member_name (method_name);
348 obstack_1grow (mangle_obstack, 'E');
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);
355 /* Output literal 'J' and mangle the return type IF not a
356 constructor. */
357 if (!ID_INIT_P (method_name))
359 obstack_1grow (mangle_obstack, 'J');
360 mangle_type(TREE_TYPE(TREE_TYPE(mdecl)));
363 /* No arguments is easy. We shortcut it. */
364 if (arglist == end_params_node)
365 obstack_1grow (mangle_obstack, 'v');
366 else
368 tree arg;
369 for (arg = arglist; arg != end_params_node; arg = TREE_CHAIN (arg))
370 mangle_type (TREE_VALUE (arg));
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. */
379 static void
380 mangle_local_cni_method_decl (tree decl)
382 MANGLE_RAW_STRING ("GA");
383 mangle_method_decl (decl);
386 /* This mangles a member name, like a function name or a field
387 name. Handle cases were `name' is a C++ keyword. Return a nonzero
388 value if unicode encoding was required. */
390 static void
391 mangle_member_name (tree name)
393 append_gpp_mangled_name (IDENTIFIER_POINTER (name),
394 IDENTIFIER_LENGTH (name));
396 /* If NAME happens to be a C++ keyword, add `$'. */
397 if (cxx_keyword_p (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name)))
398 obstack_1grow (mangle_obstack, '$');
401 /* Append the mangled name of TYPE onto OBSTACK. */
403 static void
404 mangle_type (tree type)
406 switch (TREE_CODE (type))
408 char code;
409 case BOOLEAN_TYPE: code = 'b'; goto primitive;
410 case VOID_TYPE: code = 'v'; goto primitive;
411 case INTEGER_TYPE:
412 if (type == char_type_node || type == promoted_char_type_node)
414 code = 'w';
415 goto primitive;
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))
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;
432 primitive:
433 obstack_1grow (mangle_obstack, code);
434 break;
436 case REAL_TYPE:
437 switch (TYPE_PRECISION (type))
439 case 32: code = 'f'; goto primitive;
440 case 64: code = 'd'; goto primitive;
441 default: goto bad_type;
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:
451 gcc_unreachable ();
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
457 would generate three entries: two package names and a type. If
458 java.lang.String is presented next, the java.lang will be matched
459 against the first two entries (and kept for compression as S0_), and
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. */
464 static GTY(()) tree compression_table;
465 static int compression_next;
467 /* Find a POINTER_TYPE in the compression table. Use a special
468 function to match pointer entries and start from the end */
470 static int
471 find_compression_pointer_match (tree type)
473 int i;
475 for (i = compression_next-1; i >= 0; i--)
476 if (entry_match_pointer_p (type, i))
477 return i;
478 return -1;
481 /* Already recorder arrays are handled like pointer as they're always
482 associated with it. */
484 static int
485 find_compression_array_match (tree type)
487 return find_compression_pointer_match (type);
490 /* Match the table of type against STRING. */
492 static int
493 find_compression_array_template_match (tree string)
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;
502 /* We go through the compression table and try to find a complete or
503 partial match. The function returns the compression table entry
504 that (eventually partially) matches TYPE. *NEXT_CURRENT can be set
505 to the rest of TYPE to be mangled. */
507 static int
508 find_compression_record_match (tree type, tree *next_current)
510 int i, match = -1;
511 tree current, saved_current = NULL_TREE;
513 current = TYPE_PACKAGE_LIST (type);
515 for (i = 0; i < compression_next; i++)
517 tree compression_entry = TREE_VEC_ELT (compression_table, i);
518 if (current && compression_entry == TREE_PURPOSE (current))
520 match = i;
521 saved_current = current;
522 current = TREE_CHAIN (current);
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);
535 if (!next_current)
536 return match;
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);
546 return match;
549 /* Mangle a record type. If a nonzero value is returned, it means
550 that a 'N' was emitted (so that a matching 'E' can be emitted if
551 necessary.) FOR_POINTER indicates that this element is for a pointer
552 symbol, meaning it was preceded by a 'P'. */
554 static int
555 mangle_record_type (tree type, int for_pointer)
557 tree current;
558 int match;
559 int nadded_p = 0;
560 int qualified;
562 /* Does this name have a package qualifier? */
563 qualified = QUALIFIED_P (DECL_NAME (TYPE_NAME (type)));
565 #define ADD_N() \
566 do { obstack_1grow (mangle_obstack, 'N'); nadded_p = 1; } while (0)
568 gcc_assert (TREE_CODE (type) == RECORD_TYPE);
570 if (!TYPE_PACKAGE_LIST (type))
571 set_type_package_list (type);
573 match = find_compression_record_match (type, &current);
574 if (match >= 0)
576 /* If we had a pointer, and there's more, we need to emit
577 'N' after 'P' (for_pointer tells us we already emitted it.) */
578 if (for_pointer && current)
579 ADD_N();
580 emit_compression_string (match);
582 while (current)
584 /* Add the new type to the table */
585 compression_table_add (TREE_PURPOSE (current));
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)
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);
595 return nadded_p;
596 #undef ADD_N
599 /* Mangle a pointer type. There are two cases: the pointer is already
600 in the compression table: the compression is emitted sans 'P'
601 indicator. Otherwise, a 'P' is emitted and, depending on the type,
602 a partial compression or/plus the rest of the mangling. */
604 static void
605 mangle_pointer_type (tree type)
607 int match;
608 tree pointer_type;
610 /* Search for the type already in the compression table */
611 if ((match = find_compression_pointer_match (type)) >= 0)
613 emit_compression_string (match);
614 return;
617 /* This didn't work. We start by mangling the pointed-to type */
618 pointer_type = type;
619 type = TREE_TYPE (type);
620 gcc_assert (TREE_CODE (type) == RECORD_TYPE);
622 obstack_1grow (mangle_obstack, 'P');
623 if (mangle_record_type (type, /* for_pointer = */ 1))
624 obstack_1grow (mangle_obstack, 'E');
626 /* Don't forget to insert the pointer type in the table */
627 compression_table_add (pointer_type);
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
632 the template indicator were already used and compressed appropriately.
633 It handles pointers. */
635 static void
636 mangle_array_type (tree p_type)
638 tree type, elt_type;
639 int match;
641 type = TREE_TYPE (p_type);
642 gcc_assert (type);
644 elt_type = TYPE_ARRAY_ELEMENT (type);
646 /* We cache a bit of the Jarray <> mangle. */
647 if (!atms)
649 atms = get_identifier ("6JArray");
652 /* Maybe we have what we're looking for in the compression table. */
653 if ((match = find_compression_array_match (p_type)) >= 0)
655 emit_compression_string (match);
656 return;
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)
664 emit_compression_string (match);
665 return;
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
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);
680 /* Mangle Jarray <elt_type> */
681 obstack_1grow (mangle_obstack, 'I');
682 mangle_type (elt_type);
683 obstack_1grow (mangle_obstack, 'E');
685 /* Add `Jarray <elt_type>' and `Jarray <elt_type> *' to the table */
686 compression_table_add (type);
687 compression_table_add (p_type);
690 /* Write a substitution string for entry I. Substitution string starts a
691 -1 (encoded S_.) The base is 36, and the code shamelessly taken from
692 cp/mangle.c. */
694 static void
695 emit_compression_string (int i)
697 i -= 1; /* Adjust */
698 obstack_1grow (mangle_obstack, 'S');
699 if (i >= 0)
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)
709 int digit = i / m;
710 obstack_1grow (mangle_obstack, digits [digit]);
711 i -= digit * m;
712 m /= 36;
715 obstack_1grow (mangle_obstack, '_');
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.) */
722 static int
723 entry_match_pointer_p (tree type, int i)
725 tree t = TREE_VEC_ELT (compression_table, i);
727 while (TREE_CODE (type) == POINTER_TYPE
728 && TREE_CODE (t) == POINTER_TYPE)
730 t = TREE_TYPE (t);
731 type = TREE_TYPE (type);
733 return (TREE_CODE (type) == RECORD_TYPE
734 && TREE_CODE (t) == RECORD_TYPE
735 && t == type);
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. */
743 static void
744 set_type_package_list (tree type)
746 int i;
747 const char *type_string = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
748 const char *ptr;
749 int qualifications;
750 tree list = NULL_TREE, elt;
752 for (ptr = type_string, qualifications = 0; *ptr; ptr++)
753 if (*ptr == '.')
754 qualifications += 1;
756 for (ptr = type_string, i = 0; i < qualifications; ptr++)
758 if (ptr [0] == '.')
760 tree const identifier
761 = get_identifier_with_length (type_string, ptr - type_string);
763 elt = build_tree_list (identifier, identifier);
764 TREE_CHAIN (elt) = list;
765 list = elt;
766 type_string = ptr+1;
767 i += 1;
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);
777 /* Add TYPE as the last element of the compression table. Resize the
778 compression table if necessary. */
780 static void
781 compression_table_add (tree type)
783 if (compression_next == TREE_VEC_LENGTH (compression_table))
785 tree new = make_tree_vec (2*compression_next);
786 int i;
788 for (i = 0; i < compression_next; i++)
789 TREE_VEC_ELT (new, i) = TREE_VEC_ELT (compression_table, i);
791 compression_table = new;
793 TREE_VEC_ELT (compression_table, compression_next++) = type;
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". */
802 tree
803 java_mangle_resource_name (const char *name)
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;
812 pos = buf;
814 init_mangling ();
815 MANGLE_RAW_STRING ("Gr");
817 *pos++ = '_';
818 while (w1 < limit)
820 int ch;
821 w2 = w1;
822 ch = UTF8_GET (w1, limit);
823 gcc_assert (ch > 0);
824 switch (ch)
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;
844 append_gpp_mangled_name (buf, pos - buf);
846 return finish_mangling ();
849 /* Mangling initialization routine. */
851 static void
852 init_mangling (void)
854 if (!mangle_obstack)
856 mangle_obstack = &mangle_obstack_1;
857 gcc_obstack_init (mangle_obstack);
860 gcc_assert (compression_table == NULL);
861 compression_table = make_tree_vec (10);
863 /* Mangled name are to be suffixed */
864 MANGLE_RAW_STRING ("_Z");
867 /* Mangling finalization routine. The mangled name is returned as a
868 IDENTIFIER_NODE. */
870 static tree
871 finish_mangling (void)
873 tree result;
875 gcc_assert (compression_table);
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));
883 return result;
886 #include "gt-java-mangle.h"