]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/java/mangle.c
Update Copyright years for files modified in 2011 and/or 2012.
[thirdparty/gcc.git] / gcc / java / mangle.c
CommitLineData
377029eb 1/* Functions related to mangling class names for the GNU compiler
2 for the Java(TM) language.
71e45bc2 3 Copyright (C) 1998, 1999, 2001, 2002, 2003, 2006, 2007, 2008, 2009, 2010,
4 2012 Free Software Foundation, Inc.
377029eb 5
7d82ed5e 6This file is part of GCC.
377029eb 7
7d82ed5e 8GCC is free software; you can redistribute it and/or modify
377029eb 9it under the terms of the GNU General Public License as published by
e4b52719 10the Free Software Foundation; either version 3, or (at your option)
377029eb 11any later version.
12
7d82ed5e 13GCC is distributed in the hope that it will be useful,
377029eb 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
e4b52719 19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>.
377029eb 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
377029eb 28#include "config.h"
014e6e0c 29#include "system.h"
805e22b2 30#include "coretypes.h"
377029eb 31#include "jcf.h"
003019ba 32#include "tree.h"
33#include "java-tree.h"
377029eb 34#include "obstack.h"
0b205f4c 35#include "diagnostic-core.h"
6599bf3a 36#include "ggc.h"
dc5e5216 37#include "langhooks-def.h"
6599bf3a 38
dc5e5216 39static void mangle_class_field (tree);
40static void mangle_vtable (tree);
6852521a 41static void mangle_field_decl (tree);
42static void mangle_method_decl (tree);
dc5e5216 43static void mangle_local_cni_method_decl (tree);
6599bf3a 44
6852521a 45static void mangle_type (tree);
46static void mangle_pointer_type (tree);
47static void mangle_array_type (tree);
48static int mangle_record_type (tree, int);
6599bf3a 49
6852521a 50static int find_compression_pointer_match (tree);
51static int find_compression_array_match (tree);
52static int find_compression_record_match (tree, tree *);
53static int find_compression_array_template_match (tree);
6599bf3a 54
6852521a 55static void set_type_package_list (tree);
56static int entry_match_pointer_p (tree, int);
57static void emit_compression_string (int);
6599bf3a 58
dc5e5216 59static void init_mangling (void);
6852521a 60static tree finish_mangling (void);
61static void compression_table_add (tree);
6599bf3a 62
6852521a 63static void mangle_member_name (tree);
6599bf3a 64
dc5e5216 65static struct obstack mangle_obstack_1;
6599bf3a 66struct obstack *mangle_obstack;
dc5e5216 67
6599bf3a 68#define MANGLE_RAW_STRING(S) \
69 obstack_grow (mangle_obstack, (S), sizeof (S)-1)
70
0d84bf52 71/* atms: array template mangled string. */
72static GTY(()) tree atms;
73
6599bf3a 74/* This is the mangling interface: a decl, a class field (.class) and
75 the vtable. */
76
dc5e5216 77void
78java_mangle_decl (tree decl)
6599bf3a 79{
dc5e5216 80 /* A copy of the check from the beginning of lhd_set_decl_assembler_name.
81 Only FUNCTION_DECLs and VAR_DECLs for variables with static storage
82 duration need a real DECL_ASSEMBLER_NAME. */
83 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
84 || (TREE_CODE (decl) == VAR_DECL
85 && (TREE_STATIC (decl)
86 || DECL_EXTERNAL (decl)
87 || TREE_PUBLIC (decl))));
88
89 /* Mangling only applies to class members. */
90 if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
6599bf3a 91 {
dc5e5216 92 init_mangling ();
93 switch (TREE_CODE (decl))
94 {
95 case VAR_DECL:
96 if (DECL_LANG_SPECIFIC (decl))
97 {
98 if (DECL_CLASS_FIELD_P (decl))
99 {
2934c6b5 100 mangle_class_field (decl);
dc5e5216 101 break;
102 }
103 else if (DECL_VTABLE_P (decl))
104 {
105 mangle_vtable (DECL_CONTEXT (decl));
106 break;
107 }
108 }
109 mangle_field_decl (decl);
110 break;
111
112 case FUNCTION_DECL:
113 if (DECL_LANG_SPECIFIC (decl) && DECL_LOCAL_CNI_METHOD_P (decl))
114 mangle_local_cni_method_decl (decl);
115 else
116 mangle_method_decl (decl);
117 break;
118
119 default:
120 gcc_unreachable ();
121 }
122 SET_DECL_ASSEMBLER_NAME (decl, finish_mangling ());
6599bf3a 123 }
dc5e5216 124 else
125 lhd_set_decl_assembler_name (decl);
6599bf3a 126}
127
dc5e5216 128/* Beginning of the helper functions */
129
130static void
2934c6b5 131mangle_class_field (tree decl)
6599bf3a 132{
2934c6b5 133 tree type = DECL_CONTEXT (decl);
d20d8111 134 mangle_record_type (type, /* for_pointer = */ 0);
2934c6b5 135 if (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE)
136 MANGLE_RAW_STRING ("6class$");
137 else
138 MANGLE_RAW_STRING ("7class$$");
6599bf3a 139 obstack_1grow (mangle_obstack, 'E');
6599bf3a 140}
141
dc5e5216 142static void
143mangle_vtable (tree type)
6599bf3a 144{
6599bf3a 145 MANGLE_RAW_STRING ("TV");
d20d8111 146 mangle_record_type (type, /* for_pointer = */ 0);
6599bf3a 147 obstack_1grow (mangle_obstack, 'E');
6599bf3a 148}
149
6599bf3a 150/* This mangles a field decl */
151
152static void
2883a3ed 153mangle_field_decl (tree decl)
6599bf3a 154{
6599bf3a 155 /* Mangle the name of the this the field belongs to */
d20d8111 156 mangle_record_type (DECL_CONTEXT (decl), /* for_pointer = */ 0);
6599bf3a 157
158 /* Mangle the name of the field */
bca8957b 159 mangle_member_name (DECL_NAME (decl));
6599bf3a 160
161 /* Terminate the mangled name */
162 obstack_1grow (mangle_obstack, 'E');
6599bf3a 163}
164
165/* This mangles a method decl, first mangling its name and then all
166 its arguments. */
167
168static void
2883a3ed 169mangle_method_decl (tree mdecl)
6599bf3a 170{
171 tree method_name = DECL_NAME (mdecl);
172 tree arglist;
6599bf3a 173
174 /* Mangle the name of the type that contains mdecl */
d20d8111 175 mangle_record_type (DECL_CONTEXT (mdecl), /* for_pointer = */ 0);
6599bf3a 176
e0ee4832 177 /* Mangle the function name. There are two cases:
6599bf3a 178 - mdecl is a constructor, use `C1' for its name, (denotes a
179 complete object constructor.)
180 - mdecl is not a constructor, standard mangling is performed.
181 We terminate the mangled function name with a `E'. */
182 if (ID_INIT_P (method_name))
e0ee4832 183 obstack_grow (mangle_obstack, "C1", 2);
6599bf3a 184 else
bca8957b 185 mangle_member_name (method_name);
6599bf3a 186 obstack_1grow (mangle_obstack, 'E');
187
188 /* We mangled type.methodName. Now onto the arguments. */
189 arglist = TYPE_ARG_TYPES (TREE_TYPE (mdecl));
190 if (TREE_CODE (TREE_TYPE (mdecl)) == METHOD_TYPE)
191 arglist = TREE_CHAIN (arglist);
192
4c8420c9 193 /* Output literal 'J' and mangle the return type IF not a
194 constructor. */
195 if (!ID_INIT_P (method_name))
196 {
197 obstack_1grow (mangle_obstack, 'J');
198 mangle_type(TREE_TYPE(TREE_TYPE(mdecl)));
199 }
200
6599bf3a 201 /* No arguments is easy. We shortcut it. */
202 if (arglist == end_params_node)
203 obstack_1grow (mangle_obstack, 'v');
204 else
205 {
206 tree arg;
207 for (arg = arglist; arg != end_params_node; arg = TREE_CHAIN (arg))
208 mangle_type (TREE_VALUE (arg));
209 }
6599bf3a 210}
211
dc5e5216 212/* This mangles a CNI method for a local class. If the target supports
213 hidden aliases, then G++ will have generated one for us. It is the
214 responsibility of java_mark_class_local to check target support, since
215 we need to set DECL_VISIBILITY (or not) much earlier. */
216
217static void
218mangle_local_cni_method_decl (tree decl)
219{
220 MANGLE_RAW_STRING ("GA");
221 mangle_method_decl (decl);
222}
223
6599bf3a 224/* This mangles a member name, like a function name or a field
86523f9c 225 name. Handle cases were `name' is a C++ keyword. Return a nonzero
6599bf3a 226 value if unicode encoding was required. */
227
bca8957b 228static void
2883a3ed 229mangle_member_name (tree name)
6599bf3a 230{
bca8957b 231 append_gpp_mangled_name (IDENTIFIER_POINTER (name),
232 IDENTIFIER_LENGTH (name));
377029eb 233}
234
6599bf3a 235/* Append the mangled name of TYPE onto OBSTACK. */
377029eb 236
6599bf3a 237static void
2883a3ed 238mangle_type (tree type)
6599bf3a 239{
240 switch (TREE_CODE (type))
241 {
242 char code;
243 case BOOLEAN_TYPE: code = 'b'; goto primitive;
6599bf3a 244 case VOID_TYPE: code = 'v'; goto primitive;
245 case INTEGER_TYPE:
ea347d91 246 if (type == char_type_node || type == promoted_char_type_node)
247 {
248 code = 'w';
249 goto primitive;
250 }
6599bf3a 251 /* Get the original type instead of the arguments promoted type.
252 Avoid symbol name clashes. Should call a function to do that.
253 FIXME. */
254 if (type == promoted_short_type_node)
255 type = short_type_node;
256 if (type == promoted_byte_type_node)
257 type = byte_type_node;
258 switch (TYPE_PRECISION (type))
259 {
260 case 8: code = 'c'; goto primitive;
261 case 16: code = 's'; goto primitive;
262 case 32: code = 'i'; goto primitive;
263 case 64: code = 'x'; goto primitive;
264 default: goto bad_type;
265 }
266 primitive:
267 obstack_1grow (mangle_obstack, code);
268 break;
269
270 case REAL_TYPE:
271 switch (TYPE_PRECISION (type))
272 {
273 case 32: code = 'f'; goto primitive;
274 case 64: code = 'd'; goto primitive;
275 default: goto bad_type;
276 }
277 case POINTER_TYPE:
278 if (TYPE_ARRAY_P (TREE_TYPE (type)))
279 mangle_array_type (type);
280 else
281 mangle_pointer_type (type);
282 break;
283 bad_type:
284 default:
bc031ffe 285 gcc_unreachable ();
6599bf3a 286 }
287}
288
289/* The compression table is a vector that keeps track of things we've
290 already seen, so they can be reused. For example, java.lang.Object
1df33732 291 would generate three entries: two package names and a type. If
6599bf3a 292 java.lang.String is presented next, the java.lang will be matched
0d84bf52 293 against the first two entries (and kept for compression as S0_), and
6599bf3a 294 type String would be added to the table. See mangle_record_type.
295 COMPRESSION_NEXT is the index to the location of the next insertion
296 of an element. */
297
1f3233d1 298static GTY(()) tree compression_table;
6599bf3a 299static int compression_next;
300
301/* Find a POINTER_TYPE in the compression table. Use a special
302 function to match pointer entries and start from the end */
303
304static int
2883a3ed 305find_compression_pointer_match (tree type)
6599bf3a 306{
307 int i;
308
309 for (i = compression_next-1; i >= 0; i--)
310 if (entry_match_pointer_p (type, i))
311 return i;
312 return -1;
313}
314
315/* Already recorder arrays are handled like pointer as they're always
316 associated with it. */
317
318static int
2883a3ed 319find_compression_array_match (tree type)
6599bf3a 320{
321 return find_compression_pointer_match (type);
322}
323
324/* Match the table of type against STRING. */
325
326static int
2883a3ed 327find_compression_array_template_match (tree string)
6599bf3a 328{
329 int i;
330 for (i = 0; i < compression_next; i++)
331 if (TREE_VEC_ELT (compression_table, i) == string)
332 return i;
333 return -1;
334}
335
336/* We go through the compression table and try to find a complete or
337 partial match. The function returns the compression table entry
4f9026a9 338 that (eventually partially) matches TYPE. *NEXT_CURRENT can be set
6599bf3a 339 to the rest of TYPE to be mangled. */
340
341static int
2883a3ed 342find_compression_record_match (tree type, tree *next_current)
377029eb 343{
5a13b7cd 344 int i, match = -1;
6d81beba 345 tree current, saved_current = NULL_TREE;
377029eb 346
5a13b7cd 347 current = TYPE_PACKAGE_LIST (type);
348
349 for (i = 0; i < compression_next; i++)
377029eb 350 {
5a13b7cd 351 tree compression_entry = TREE_VEC_ELT (compression_table, i);
352 if (current && compression_entry == TREE_PURPOSE (current))
353 {
354 match = i;
355 saved_current = current;
356 current = TREE_CHAIN (current);
357 }
358 else
359 /* We don't want to match an element that appears in the middle
360 of a package name, so skip forward to the next complete type name.
361 IDENTIFIER_NODEs (except for a "6JArray") are partial package
362 names while RECORD_TYPEs represent complete type names. */
363 while (i < compression_next
364 && TREE_CODE (compression_entry) == IDENTIFIER_NODE
365 && compression_entry != atms)
366 compression_entry = TREE_VEC_ELT (compression_table, ++i);
6599bf3a 367 }
368
369 if (!next_current)
370 return match;
371
372 /* If we have a match, set next_current to the item next to the last
373 matched value. */
374 if (match >= 0)
375 *next_current = TREE_CHAIN (saved_current);
376 /* We had no match: we'll have to start from the beginning. */
377 if (match < 0)
378 *next_current = TYPE_PACKAGE_LIST (type);
379
380 return match;
381}
382
86523f9c 383/* Mangle a record type. If a nonzero value is returned, it means
6599bf3a 384 that a 'N' was emitted (so that a matching 'E' can be emitted if
d20d8111 385 necessary.) FOR_POINTER indicates that this element is for a pointer
386 symbol, meaning it was preceded by a 'P'. */
6599bf3a 387
388static int
2883a3ed 389mangle_record_type (tree type, int for_pointer)
6599bf3a 390{
391 tree current;
392 int match;
393 int nadded_p = 0;
d20d8111 394 int qualified;
395
396 /* Does this name have a package qualifier? */
397 qualified = QUALIFIED_P (DECL_NAME (TYPE_NAME (type)));
6599bf3a 398
399#define ADD_N() \
400 do { obstack_1grow (mangle_obstack, 'N'); nadded_p = 1; } while (0)
401
bc031ffe 402 gcc_assert (TREE_CODE (type) == RECORD_TYPE);
6599bf3a 403
404 if (!TYPE_PACKAGE_LIST (type))
405 set_type_package_list (type);
406
407 match = find_compression_record_match (type, &current);
408 if (match >= 0)
409 {
410 /* If we had a pointer, and there's more, we need to emit
d20d8111 411 'N' after 'P' (for_pointer tells us we already emitted it.) */
412 if (for_pointer && current)
6599bf3a 413 ADD_N();
414 emit_compression_string (match);
377029eb 415 }
6599bf3a 416 while (current)
377029eb 417 {
6599bf3a 418 /* Add the new type to the table */
419 compression_table_add (TREE_PURPOSE (current));
d20d8111 420 /* Add 'N' if we never got a chance to, but only if we have a qualified
421 name. For non-pointer elements, the name is always qualified. */
422 if ((qualified || !for_pointer) && !nadded_p)
6599bf3a 423 ADD_N();
424 /* Use the bare type name for the mangle. */
425 append_gpp_mangled_name (IDENTIFIER_POINTER (TREE_VALUE (current)),
426 IDENTIFIER_LENGTH (TREE_VALUE (current)));
427 current = TREE_CHAIN (current);
428 }
429 return nadded_p;
430#undef ADD_N
431}
432
433/* Mangle a pointer type. There are two cases: the pointer is already
4f9026a9 434 in the compression table: the compression is emitted sans 'P'
6599bf3a 435 indicator. Otherwise, a 'P' is emitted and, depending on the type,
436 a partial compression or/plus the rest of the mangling. */
437
438static void
2883a3ed 439mangle_pointer_type (tree type)
6599bf3a 440{
441 int match;
442 tree pointer_type;
443
444 /* Search for the type already in the compression table */
445 if ((match = find_compression_pointer_match (type)) >= 0)
446 {
447 emit_compression_string (match);
448 return;
377029eb 449 }
6599bf3a 450
451 /* This didn't work. We start by mangling the pointed-to type */
452 pointer_type = type;
453 type = TREE_TYPE (type);
bc031ffe 454 gcc_assert (TREE_CODE (type) == RECORD_TYPE);
6599bf3a 455
456 obstack_1grow (mangle_obstack, 'P');
457 if (mangle_record_type (type, /* for_pointer = */ 1))
458 obstack_1grow (mangle_obstack, 'E');
459
460 /* Don't forget to insert the pointer type in the table */
461 compression_table_add (pointer_type);
462}
463
464/* Mangle an array type. Search for an easy solution first, then go
465 through the process of finding out whether the bare array type or even
0d84bf52 466 the template indicator were already used and compressed appropriately.
6599bf3a 467 It handles pointers. */
468
469static void
2883a3ed 470mangle_array_type (tree p_type)
6599bf3a 471{
6599bf3a 472 tree type, elt_type;
473 int match;
474
475 type = TREE_TYPE (p_type);
bc031ffe 476 gcc_assert (type);
f060a027 477
6599bf3a 478 elt_type = TYPE_ARRAY_ELEMENT (type);
479
480 /* We cache a bit of the Jarray <> mangle. */
481 if (!atms)
482 {
483 atms = get_identifier ("6JArray");
6599bf3a 484 }
485
0d84bf52 486 /* Maybe we have what we're looking for in the compression table. */
6599bf3a 487 if ((match = find_compression_array_match (p_type)) >= 0)
488 {
489 emit_compression_string (match);
490 return;
491 }
492
493 /* We know for a fact that all arrays are pointers */
494 obstack_1grow (mangle_obstack, 'P');
495 /* Maybe we already have a Jarray<t> somewhere. PSx_ will be enough. */
496 if ((match = find_compression_record_match (type, NULL)) > 0)
497 {
498 emit_compression_string (match);
499 return;
500 }
501
502 /* Maybe we already have just JArray somewhere */
503 if ((match = find_compression_array_template_match (atms)) > 0)
504 emit_compression_string (match);
505 else
377029eb 506 {
6599bf3a 507 /* Start the template mangled name */
508 obstack_grow (mangle_obstack,
509 IDENTIFIER_POINTER (atms), IDENTIFIER_LENGTH (atms));
510 /* Insert in the compression table */
511 compression_table_add (atms);
512 }
513
514 /* Mangle Jarray <elt_type> */
515 obstack_1grow (mangle_obstack, 'I');
516 mangle_type (elt_type);
517 obstack_1grow (mangle_obstack, 'E');
518
519 /* Add `Jarray <elt_type>' and `Jarray <elt_type> *' to the table */
520 compression_table_add (type);
521 compression_table_add (p_type);
522}
523
4f9026a9 524/* Write a substitution string for entry I. Substitution string starts a
ce2012e7 525 -1 (encoded S_.) The base is 36, and the code shamelessly taken from
6599bf3a 526 cp/mangle.c. */
527
528static void
529emit_compression_string (int i)
530{
531 i -= 1; /* Adjust */
532 obstack_1grow (mangle_obstack, 'S');
533 if (i >= 0)
534 {
535 static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
536 unsigned HOST_WIDE_INT n;
537 unsigned HOST_WIDE_INT m=1;
538 /* How many digits for I in base 36? */
539 for (n = i; n >= 36; n /= 36, m *=36);
540 /* Write the digits out */
541 while (m > 0)
377029eb 542 {
6599bf3a 543 int digit = i / m;
544 obstack_1grow (mangle_obstack, digits [digit]);
545 i -= digit * m;
546 m /= 36;
547 }
548 }
549 obstack_1grow (mangle_obstack, '_');
550}
551
552/* If search the compression table at index I for a pointer type
553 equivalent to TYPE (meaning that after all the indirection, which
554 might all be unique, we find the same RECORD_TYPE.) */
555
556static int
2883a3ed 557entry_match_pointer_p (tree type, int i)
6599bf3a 558{
559 tree t = TREE_VEC_ELT (compression_table, i);
560
561 while (TREE_CODE (type) == POINTER_TYPE
562 && TREE_CODE (t) == POINTER_TYPE)
563 {
564 t = TREE_TYPE (t);
565 type = TREE_TYPE (type);
566 }
567 return (TREE_CODE (type) == RECORD_TYPE
568 && TREE_CODE (t) == RECORD_TYPE
569 && t == type);
570}
571
572/* Go through all qualification of type and build a list of list node
573 elements containings as a purpose what should be used for a match and
574 inserted in the compression table; and as it value the raw name of the
575 part. The result is stored in TYPE_PACKAGE_LIST to be reused. */
576
577static void
2883a3ed 578set_type_package_list (tree type)
6599bf3a 579{
580 int i;
581 const char *type_string = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
920a6d94 582 const char *ptr;
6599bf3a 583 int qualifications;
584 tree list = NULL_TREE, elt;
585
920a6d94 586 for (ptr = type_string, qualifications = 0; *ptr; ptr++)
6599bf3a 587 if (*ptr == '.')
588 qualifications += 1;
589
920a6d94 590 for (ptr = type_string, i = 0; i < qualifications; ptr++)
6599bf3a 591 {
592 if (ptr [0] == '.')
593 {
920a6d94 594 tree const identifier
595 = get_identifier_with_length (type_string, ptr - type_string);
596
6599bf3a 597 elt = build_tree_list (identifier, identifier);
598 TREE_CHAIN (elt) = list;
599 list = elt;
600 type_string = ptr+1;
601 i += 1;
377029eb 602 }
603 }
6599bf3a 604
605 elt = build_tree_list (type, get_identifier (type_string));
606 TREE_CHAIN (elt) = list;
607 list = elt;
608 TYPE_PACKAGE_LIST (type) = nreverse (list);
609}
610
611/* Add TYPE as the last element of the compression table. Resize the
612 compression table if necessary. */
613
614static void
2883a3ed 615compression_table_add (tree type)
6599bf3a 616{
617 if (compression_next == TREE_VEC_LENGTH (compression_table))
618 {
ead29d98 619 tree new_table = make_tree_vec (2*compression_next);
6599bf3a 620 int i;
621
622 for (i = 0; i < compression_next; i++)
ead29d98 623 TREE_VEC_ELT (new_table, i) = TREE_VEC_ELT (compression_table, i);
6599bf3a 624
ead29d98 625 compression_table = new_table;
6599bf3a 626 }
627 TREE_VEC_ELT (compression_table, compression_next++) = type;
628}
629
0ac26f75 630/* Mangle an embedded resource file name. "_ZGr" is the prefix. A
631 '_' is prepended to the name so that names starting with a digit
632 can be demangled. The length and then the resulting name itself
633 are appended while escaping '$', '.', and '/' to: "$$", "$_", and
634 "$S". */
635
636tree
637java_mangle_resource_name (const char *name)
638{
639 int len = strlen (name);
640 char *buf = (char *) alloca (2 * len + 1);
641 char *pos;
642 const unsigned char *w1 = (const unsigned char *) name;
643 const unsigned char *w2;
644 const unsigned char *limit = w1 + len;
645
646 pos = buf;
647
648 init_mangling ();
649 MANGLE_RAW_STRING ("Gr");
650
651 *pos++ = '_';
652 while (w1 < limit)
653 {
654 int ch;
655 w2 = w1;
656 ch = UTF8_GET (w1, limit);
657 gcc_assert (ch > 0);
658 switch (ch)
659 {
660 case '$':
661 *pos++ = '$';
662 *pos++ = '$';
663 break;
664 case '.':
665 *pos++ = '$';
666 *pos++ = '_';
667 break;
668 case '/':
669 *pos++ = '$';
670 *pos++ = 'S';
671 break;
672 default:
673 memcpy (pos, w2, w1 - w2);
674 pos += w1 - w2;
675 break;
676 }
677 }
678 append_gpp_mangled_name (buf, pos - buf);
679
680 return finish_mangling ();
681}
682
6599bf3a 683/* Mangling initialization routine. */
684
685static void
dc5e5216 686init_mangling (void)
6599bf3a 687{
dc5e5216 688 if (!mangle_obstack)
689 {
690 mangle_obstack = &mangle_obstack_1;
691 gcc_obstack_init (mangle_obstack);
692 }
693
694 gcc_assert (compression_table == NULL);
695 compression_table = make_tree_vec (10);
6599bf3a 696
697 /* Mangled name are to be suffixed */
dc5e5216 698 MANGLE_RAW_STRING ("_Z");
6599bf3a 699}
700
701/* Mangling finalization routine. The mangled name is returned as a
702 IDENTIFIER_NODE. */
703
704static tree
2883a3ed 705finish_mangling (void)
6599bf3a 706{
707 tree result;
708
dc5e5216 709 gcc_assert (compression_table);
6599bf3a 710
6599bf3a 711 compression_table = NULL_TREE;
712 compression_next = 0;
713 obstack_1grow (mangle_obstack, '\0');
714 result = get_identifier (obstack_base (mangle_obstack));
715 obstack_free (mangle_obstack, obstack_base (mangle_obstack));
dc5e5216 716
6599bf3a 717 return result;
377029eb 718}
1f3233d1 719
720#include "gt-java-mangle.h"