boehm.c: Don't use bitmap as gc_descr if pointer is misaligned.
[gcc.git] / gcc / java / mangle.c
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.
5
6 This file is part of GCC.
7
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.
12
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.
17
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/>.
21
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. */
25
26 /* Written by Per Bothner <bothner@cygnus.com> */
27
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"
39
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);
45
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);
50
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);
55
56 static void set_type_package_list (tree);
57 static int entry_match_pointer_p (tree, int);
58 static void emit_compression_string (int);
59
60 static void init_mangling (void);
61 static tree finish_mangling (void);
62 static void compression_table_add (tree);
63
64 static void mangle_member_name (tree);
65
66 static struct obstack mangle_obstack_1;
67 struct obstack *mangle_obstack;
68
69 #define MANGLE_RAW_STRING(S) \
70 obstack_grow (mangle_obstack, (S), sizeof (S)-1)
71
72 /* atms: array template mangled string. */
73 static GTY(()) tree atms;
74
75 static int
76 utf8_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. */
92 static 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. */
201 static int
202 cxx_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
236 /* This is the mangling interface: a decl, a class field (.class) and
237 the vtable. */
238
239 void
240 java_mangle_decl (tree decl)
241 {
242 if (TREE_CODE (decl) == RECORD_TYPE)
243 mangle_type (decl);
244
245 /* A copy of the check from the beginning of lhd_set_decl_assembler_name.
246 Only FUNCTION_DECLs and VAR_DECLs for variables with static storage
247 duration need a real DECL_ASSEMBLER_NAME. */
248 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
249 || (TREE_CODE (decl) == VAR_DECL
250 && (TREE_STATIC (decl)
251 || DECL_EXTERNAL (decl)
252 || TREE_PUBLIC (decl))));
253
254 /* Mangling only applies to class members. */
255 if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
256 {
257 init_mangling ();
258 switch (TREE_CODE (decl))
259 {
260 case VAR_DECL:
261 if (DECL_LANG_SPECIFIC (decl))
262 {
263 if (DECL_CLASS_FIELD_P (decl))
264 {
265 mangle_class_field (decl);
266 break;
267 }
268 else if (DECL_VTABLE_P (decl))
269 {
270 mangle_vtable (DECL_CONTEXT (decl));
271 break;
272 }
273 }
274 mangle_field_decl (decl);
275 break;
276
277 case FUNCTION_DECL:
278 if (DECL_LANG_SPECIFIC (decl) && DECL_LOCAL_CNI_METHOD_P (decl))
279 mangle_local_cni_method_decl (decl);
280 else
281 mangle_method_decl (decl);
282 break;
283
284 default:
285 gcc_unreachable ();
286 }
287 SET_DECL_ASSEMBLER_NAME (decl, finish_mangling ());
288 }
289 else
290 lhd_set_decl_assembler_name (decl);
291 }
292
293 /* Beginning of the helper functions */
294
295 static void
296 mangle_class_field (tree decl)
297 {
298 tree type = DECL_CONTEXT (decl);
299 mangle_record_type (type, /* for_pointer = */ 0);
300 if (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE)
301 MANGLE_RAW_STRING ("6class$");
302 else
303 MANGLE_RAW_STRING ("7class$$");
304 obstack_1grow (mangle_obstack, 'E');
305 }
306
307 static void
308 mangle_vtable (tree type)
309 {
310 MANGLE_RAW_STRING ("TV");
311 mangle_record_type (type, /* for_pointer = */ 0);
312 obstack_1grow (mangle_obstack, 'E');
313 }
314
315 /* This mangles a field decl */
316
317 static void
318 mangle_field_decl (tree decl)
319 {
320 /* Mangle the name of the this the field belongs to */
321 mangle_record_type (DECL_CONTEXT (decl), /* for_pointer = */ 0);
322
323 /* Mangle the name of the field */
324 mangle_member_name (DECL_NAME (decl));
325
326 /* Terminate the mangled name */
327 obstack_1grow (mangle_obstack, 'E');
328 }
329
330 /* This mangles a method decl, first mangling its name and then all
331 its arguments. */
332
333 static void
334 mangle_method_decl (tree mdecl)
335 {
336 tree method_name = DECL_NAME (mdecl);
337 tree arglist;
338
339 /* Mangle the name of the type that contains mdecl */
340 mangle_record_type (DECL_CONTEXT (mdecl), /* for_pointer = */ 0);
341
342 /* Mangle the function name. There are two cases:
343 - mdecl is a constructor, use `C1' for its name, (denotes a
344 complete object constructor.)
345 - mdecl is not a constructor, standard mangling is performed.
346 We terminate the mangled function name with a `E'. */
347 if (ID_INIT_P (method_name))
348 obstack_grow (mangle_obstack, "C1", 2);
349 else
350 mangle_member_name (method_name);
351 obstack_1grow (mangle_obstack, 'E');
352
353 /* We mangled type.methodName. Now onto the arguments. */
354 arglist = TYPE_ARG_TYPES (TREE_TYPE (mdecl));
355 if (TREE_CODE (TREE_TYPE (mdecl)) == METHOD_TYPE)
356 arglist = TREE_CHAIN (arglist);
357
358 /* Output literal 'J' and mangle the return type IF not a
359 constructor. */
360 if (!ID_INIT_P (method_name))
361 {
362 obstack_1grow (mangle_obstack, 'J');
363 mangle_type(TREE_TYPE(TREE_TYPE(mdecl)));
364 }
365
366 /* No arguments is easy. We shortcut it. */
367 if (arglist == end_params_node)
368 obstack_1grow (mangle_obstack, 'v');
369 else
370 {
371 tree arg;
372 for (arg = arglist; arg != end_params_node; arg = TREE_CHAIN (arg))
373 mangle_type (TREE_VALUE (arg));
374 }
375 }
376
377 /* This mangles a CNI method for a local class. If the target supports
378 hidden aliases, then G++ will have generated one for us. It is the
379 responsibility of java_mark_class_local to check target support, since
380 we need to set DECL_VISIBILITY (or not) much earlier. */
381
382 static void
383 mangle_local_cni_method_decl (tree decl)
384 {
385 MANGLE_RAW_STRING ("GA");
386 mangle_method_decl (decl);
387 }
388
389 /* This mangles a member name, like a function name or a field
390 name. Handle cases were `name' is a C++ keyword. Return a nonzero
391 value if unicode encoding was required. */
392
393 static void
394 mangle_member_name (tree name)
395 {
396 append_gpp_mangled_name (IDENTIFIER_POINTER (name),
397 IDENTIFIER_LENGTH (name));
398
399 /* If NAME happens to be a C++ keyword, add `$'. */
400 if (cxx_keyword_p (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name)))
401 obstack_1grow (mangle_obstack, '$');
402 }
403
404 /* Append the mangled name of TYPE onto OBSTACK. */
405
406 static void
407 mangle_type (tree type)
408 {
409 switch (TREE_CODE (type))
410 {
411 char code;
412 case BOOLEAN_TYPE: code = 'b'; goto primitive;
413 case VOID_TYPE: code = 'v'; goto primitive;
414 case INTEGER_TYPE:
415 if (type == char_type_node || type == promoted_char_type_node)
416 {
417 code = 'w';
418 goto primitive;
419 }
420 /* Get the original type instead of the arguments promoted type.
421 Avoid symbol name clashes. Should call a function to do that.
422 FIXME. */
423 if (type == promoted_short_type_node)
424 type = short_type_node;
425 if (type == promoted_byte_type_node)
426 type = byte_type_node;
427 switch (TYPE_PRECISION (type))
428 {
429 case 8: code = 'c'; goto primitive;
430 case 16: code = 's'; goto primitive;
431 case 32: code = 'i'; goto primitive;
432 case 64: code = 'x'; goto primitive;
433 default: goto bad_type;
434 }
435 primitive:
436 obstack_1grow (mangle_obstack, code);
437 break;
438
439 case REAL_TYPE:
440 switch (TYPE_PRECISION (type))
441 {
442 case 32: code = 'f'; goto primitive;
443 case 64: code = 'd'; goto primitive;
444 default: goto bad_type;
445 }
446 case POINTER_TYPE:
447 if (TYPE_ARRAY_P (TREE_TYPE (type)))
448 mangle_array_type (type);
449 else
450 mangle_pointer_type (type);
451 break;
452 bad_type:
453 default:
454 gcc_unreachable ();
455 }
456 }
457
458 /* The compression table is a vector that keeps track of things we've
459 already seen, so they can be reused. For example, java.lang.Object
460 would generate three entries: two package names and a type. If
461 java.lang.String is presented next, the java.lang will be matched
462 against the first two entries (and kept for compression as S0_), and
463 type String would be added to the table. See mangle_record_type.
464 COMPRESSION_NEXT is the index to the location of the next insertion
465 of an element. */
466
467 static GTY(()) tree compression_table;
468 static int compression_next;
469
470 /* Find a POINTER_TYPE in the compression table. Use a special
471 function to match pointer entries and start from the end */
472
473 static int
474 find_compression_pointer_match (tree type)
475 {
476 int i;
477
478 for (i = compression_next-1; i >= 0; i--)
479 if (entry_match_pointer_p (type, i))
480 return i;
481 return -1;
482 }
483
484 /* Already recorder arrays are handled like pointer as they're always
485 associated with it. */
486
487 static int
488 find_compression_array_match (tree type)
489 {
490 return find_compression_pointer_match (type);
491 }
492
493 /* Match the table of type against STRING. */
494
495 static int
496 find_compression_array_template_match (tree string)
497 {
498 int i;
499 for (i = 0; i < compression_next; i++)
500 if (TREE_VEC_ELT (compression_table, i) == string)
501 return i;
502 return -1;
503 }
504
505 /* We go through the compression table and try to find a complete or
506 partial match. The function returns the compression table entry
507 that (eventually partially) matches TYPE. *NEXT_CURRENT can be set
508 to the rest of TYPE to be mangled. */
509
510 static int
511 find_compression_record_match (tree type, tree *next_current)
512 {
513 int i, match = -1;
514 tree current, saved_current = NULL_TREE;
515
516 current = TYPE_PACKAGE_LIST (type);
517
518 for (i = 0; i < compression_next; i++)
519 {
520 tree compression_entry = TREE_VEC_ELT (compression_table, i);
521 if (current && compression_entry == TREE_PURPOSE (current))
522 {
523 match = i;
524 saved_current = current;
525 current = TREE_CHAIN (current);
526 }
527 else
528 /* We don't want to match an element that appears in the middle
529 of a package name, so skip forward to the next complete type name.
530 IDENTIFIER_NODEs (except for a "6JArray") are partial package
531 names while RECORD_TYPEs represent complete type names. */
532 while (i < compression_next
533 && TREE_CODE (compression_entry) == IDENTIFIER_NODE
534 && compression_entry != atms)
535 compression_entry = TREE_VEC_ELT (compression_table, ++i);
536 }
537
538 if (!next_current)
539 return match;
540
541 /* If we have a match, set next_current to the item next to the last
542 matched value. */
543 if (match >= 0)
544 *next_current = TREE_CHAIN (saved_current);
545 /* We had no match: we'll have to start from the beginning. */
546 if (match < 0)
547 *next_current = TYPE_PACKAGE_LIST (type);
548
549 return match;
550 }
551
552 /* Mangle a record type. If a nonzero value is returned, it means
553 that a 'N' was emitted (so that a matching 'E' can be emitted if
554 necessary.) FOR_POINTER indicates that this element is for a pointer
555 symbol, meaning it was preceded by a 'P'. */
556
557 static int
558 mangle_record_type (tree type, int for_pointer)
559 {
560 tree current;
561 int match;
562 int nadded_p = 0;
563 int qualified;
564
565 /* Does this name have a package qualifier? */
566 qualified = QUALIFIED_P (DECL_NAME (TYPE_NAME (type)));
567
568 #define ADD_N() \
569 do { obstack_1grow (mangle_obstack, 'N'); nadded_p = 1; } while (0)
570
571 gcc_assert (TREE_CODE (type) == RECORD_TYPE);
572
573 if (!TYPE_PACKAGE_LIST (type))
574 set_type_package_list (type);
575
576 match = find_compression_record_match (type, &current);
577 if (match >= 0)
578 {
579 /* If we had a pointer, and there's more, we need to emit
580 'N' after 'P' (for_pointer tells us we already emitted it.) */
581 if (for_pointer && current)
582 ADD_N();
583 emit_compression_string (match);
584 }
585 while (current)
586 {
587 /* Add the new type to the table */
588 compression_table_add (TREE_PURPOSE (current));
589 /* Add 'N' if we never got a chance to, but only if we have a qualified
590 name. For non-pointer elements, the name is always qualified. */
591 if ((qualified || !for_pointer) && !nadded_p)
592 ADD_N();
593 /* Use the bare type name for the mangle. */
594 append_gpp_mangled_name (IDENTIFIER_POINTER (TREE_VALUE (current)),
595 IDENTIFIER_LENGTH (TREE_VALUE (current)));
596 current = TREE_CHAIN (current);
597 }
598 return nadded_p;
599 #undef ADD_N
600 }
601
602 /* Mangle a pointer type. There are two cases: the pointer is already
603 in the compression table: the compression is emitted sans 'P'
604 indicator. Otherwise, a 'P' is emitted and, depending on the type,
605 a partial compression or/plus the rest of the mangling. */
606
607 static void
608 mangle_pointer_type (tree type)
609 {
610 int match;
611 tree pointer_type;
612
613 /* Search for the type already in the compression table */
614 if ((match = find_compression_pointer_match (type)) >= 0)
615 {
616 emit_compression_string (match);
617 return;
618 }
619
620 /* This didn't work. We start by mangling the pointed-to type */
621 pointer_type = type;
622 type = TREE_TYPE (type);
623 gcc_assert (TREE_CODE (type) == RECORD_TYPE);
624
625 obstack_1grow (mangle_obstack, 'P');
626 if (mangle_record_type (type, /* for_pointer = */ 1))
627 obstack_1grow (mangle_obstack, 'E');
628
629 /* Don't forget to insert the pointer type in the table */
630 compression_table_add (pointer_type);
631 }
632
633 /* Mangle an array type. Search for an easy solution first, then go
634 through the process of finding out whether the bare array type or even
635 the template indicator were already used and compressed appropriately.
636 It handles pointers. */
637
638 static void
639 mangle_array_type (tree p_type)
640 {
641 tree type, elt_type;
642 int match;
643
644 type = TREE_TYPE (p_type);
645 gcc_assert (type);
646
647 elt_type = TYPE_ARRAY_ELEMENT (type);
648
649 /* We cache a bit of the Jarray <> mangle. */
650 if (!atms)
651 {
652 atms = get_identifier ("6JArray");
653 }
654
655 /* Maybe we have what we're looking for in the compression table. */
656 if ((match = find_compression_array_match (p_type)) >= 0)
657 {
658 emit_compression_string (match);
659 return;
660 }
661
662 /* We know for a fact that all arrays are pointers */
663 obstack_1grow (mangle_obstack, 'P');
664 /* Maybe we already have a Jarray<t> somewhere. PSx_ will be enough. */
665 if ((match = find_compression_record_match (type, NULL)) > 0)
666 {
667 emit_compression_string (match);
668 return;
669 }
670
671 /* Maybe we already have just JArray somewhere */
672 if ((match = find_compression_array_template_match (atms)) > 0)
673 emit_compression_string (match);
674 else
675 {
676 /* Start the template mangled name */
677 obstack_grow (mangle_obstack,
678 IDENTIFIER_POINTER (atms), IDENTIFIER_LENGTH (atms));
679 /* Insert in the compression table */
680 compression_table_add (atms);
681 }
682
683 /* Mangle Jarray <elt_type> */
684 obstack_1grow (mangle_obstack, 'I');
685 mangle_type (elt_type);
686 obstack_1grow (mangle_obstack, 'E');
687
688 /* Add `Jarray <elt_type>' and `Jarray <elt_type> *' to the table */
689 compression_table_add (type);
690 compression_table_add (p_type);
691 }
692
693 /* Write a substitution string for entry I. Substitution string starts a
694 -1 (encoded S_.) The base is 36, and the code shamelessly taken from
695 cp/mangle.c. */
696
697 static void
698 emit_compression_string (int i)
699 {
700 i -= 1; /* Adjust */
701 obstack_1grow (mangle_obstack, 'S');
702 if (i >= 0)
703 {
704 static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
705 unsigned HOST_WIDE_INT n;
706 unsigned HOST_WIDE_INT m=1;
707 /* How many digits for I in base 36? */
708 for (n = i; n >= 36; n /= 36, m *=36);
709 /* Write the digits out */
710 while (m > 0)
711 {
712 int digit = i / m;
713 obstack_1grow (mangle_obstack, digits [digit]);
714 i -= digit * m;
715 m /= 36;
716 }
717 }
718 obstack_1grow (mangle_obstack, '_');
719 }
720
721 /* If search the compression table at index I for a pointer type
722 equivalent to TYPE (meaning that after all the indirection, which
723 might all be unique, we find the same RECORD_TYPE.) */
724
725 static int
726 entry_match_pointer_p (tree type, int i)
727 {
728 tree t = TREE_VEC_ELT (compression_table, i);
729
730 while (TREE_CODE (type) == POINTER_TYPE
731 && TREE_CODE (t) == POINTER_TYPE)
732 {
733 t = TREE_TYPE (t);
734 type = TREE_TYPE (type);
735 }
736 return (TREE_CODE (type) == RECORD_TYPE
737 && TREE_CODE (t) == RECORD_TYPE
738 && t == type);
739 }
740
741 /* Go through all qualification of type and build a list of list node
742 elements containings as a purpose what should be used for a match and
743 inserted in the compression table; and as it value the raw name of the
744 part. The result is stored in TYPE_PACKAGE_LIST to be reused. */
745
746 static void
747 set_type_package_list (tree type)
748 {
749 int i;
750 const char *type_string = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
751 const char *ptr;
752 int qualifications;
753 tree list = NULL_TREE, elt;
754
755 for (ptr = type_string, qualifications = 0; *ptr; ptr++)
756 if (*ptr == '.')
757 qualifications += 1;
758
759 for (ptr = type_string, i = 0; i < qualifications; ptr++)
760 {
761 if (ptr [0] == '.')
762 {
763 tree const identifier
764 = get_identifier_with_length (type_string, ptr - type_string);
765
766 elt = build_tree_list (identifier, identifier);
767 TREE_CHAIN (elt) = list;
768 list = elt;
769 type_string = ptr+1;
770 i += 1;
771 }
772 }
773
774 elt = build_tree_list (type, get_identifier (type_string));
775 TREE_CHAIN (elt) = list;
776 list = elt;
777 TYPE_PACKAGE_LIST (type) = nreverse (list);
778 }
779
780 /* Add TYPE as the last element of the compression table. Resize the
781 compression table if necessary. */
782
783 static void
784 compression_table_add (tree type)
785 {
786 if (compression_next == TREE_VEC_LENGTH (compression_table))
787 {
788 tree new = make_tree_vec (2*compression_next);
789 int i;
790
791 for (i = 0; i < compression_next; i++)
792 TREE_VEC_ELT (new, i) = TREE_VEC_ELT (compression_table, i);
793
794 compression_table = new;
795 }
796 TREE_VEC_ELT (compression_table, compression_next++) = type;
797 }
798
799 /* Mangling initialization routine. */
800
801 static void
802 init_mangling (void)
803 {
804 if (!mangle_obstack)
805 {
806 mangle_obstack = &mangle_obstack_1;
807 gcc_obstack_init (mangle_obstack);
808 }
809
810 gcc_assert (compression_table == NULL);
811 compression_table = make_tree_vec (10);
812
813 /* Mangled name are to be suffixed */
814 MANGLE_RAW_STRING ("_Z");
815 }
816
817 /* Mangling finalization routine. The mangled name is returned as a
818 IDENTIFIER_NODE. */
819
820 static tree
821 finish_mangling (void)
822 {
823 tree result;
824
825 gcc_assert (compression_table);
826
827 compression_table = NULL_TREE;
828 compression_next = 0;
829 obstack_1grow (mangle_obstack, '\0');
830 result = get_identifier (obstack_base (mangle_obstack));
831 obstack_free (mangle_obstack, obstack_base (mangle_obstack));
832
833 return result;
834 }
835
836 #include "gt-java-mangle.h"