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