OSDN Git Service

Update test to follow Ada 2005 rules.
[pf3gnuchains/gcc-fork.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"