Update .po files.
[official-gcc.git] / gcc / java / mangle.c
blob6c33396c3420f765a93aa28edc0c65abab82f96c
1 /* Functions related to mangling class names for the GNU compiler
2 for the Java(TM) language.
3 Copyright (C) 1998-2016 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>.
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc. */
25 /* Written by Per Bothner <bothner@cygnus.com> */
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tree.h"
31 #include "stringpool.h"
32 #include "jcf.h"
33 #include "java-tree.h"
34 #include "langhooks-def.h"
36 static void mangle_class_field (tree);
37 static void mangle_vtable (tree);
38 static void mangle_field_decl (tree);
39 static void mangle_method_decl (tree);
40 static void mangle_local_cni_method_decl (tree);
42 static void mangle_type (tree);
43 static void mangle_pointer_type (tree);
44 static void mangle_array_type (tree);
45 static int mangle_record_type (tree, int);
47 static int find_compression_pointer_match (tree);
48 static int find_compression_array_match (tree);
49 static int find_compression_record_match (tree, tree *);
50 static int find_compression_array_template_match (tree);
52 static void set_type_package_list (tree);
53 static int entry_match_pointer_p (tree, int);
54 static void emit_compression_string (int);
56 static void init_mangling (void);
57 static tree finish_mangling (void);
58 static void compression_table_add (tree);
60 static void mangle_member_name (tree);
62 static struct obstack mangle_obstack_1;
63 struct obstack *mangle_obstack;
65 #define MANGLE_RAW_STRING(S) \
66 obstack_grow (mangle_obstack, (S), sizeof (S)-1)
68 /* atms: array template mangled string. */
69 static GTY(()) tree atms;
71 /* This is the mangling interface: a decl, a class field (.class) and
72 the vtable. */
74 void
75 java_mangle_decl (tree decl)
77 /* A copy of the check from the beginning of lhd_set_decl_assembler_name.
78 Only FUNCTION_DECLs and VAR_DECLs for variables with static storage
79 duration need a real DECL_ASSEMBLER_NAME. */
80 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
81 || (TREE_CODE (decl) == VAR_DECL
82 && (TREE_STATIC (decl)
83 || DECL_EXTERNAL (decl)
84 || TREE_PUBLIC (decl))));
86 /* Mangling only applies to class members. */
87 if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
89 init_mangling ();
90 switch (TREE_CODE (decl))
92 case VAR_DECL:
93 if (DECL_LANG_SPECIFIC (decl))
95 if (DECL_CLASS_FIELD_P (decl))
97 mangle_class_field (decl);
98 break;
100 else if (DECL_VTABLE_P (decl))
102 mangle_vtable (DECL_CONTEXT (decl));
103 break;
106 mangle_field_decl (decl);
107 break;
109 case FUNCTION_DECL:
110 if (DECL_LANG_SPECIFIC (decl) && DECL_LOCAL_CNI_METHOD_P (decl))
111 mangle_local_cni_method_decl (decl);
112 else
113 mangle_method_decl (decl);
114 break;
116 default:
117 gcc_unreachable ();
119 SET_DECL_ASSEMBLER_NAME (decl, finish_mangling ());
121 else
122 lhd_set_decl_assembler_name (decl);
125 /* Beginning of the helper functions */
127 static void
128 mangle_class_field (tree decl)
130 tree type = DECL_CONTEXT (decl);
131 mangle_record_type (type, /* for_pointer = */ 0);
132 if (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE)
133 MANGLE_RAW_STRING ("6class$");
134 else
135 MANGLE_RAW_STRING ("7class$$");
136 obstack_1grow (mangle_obstack, 'E');
139 static void
140 mangle_vtable (tree type)
142 MANGLE_RAW_STRING ("TV");
143 mangle_record_type (type, /* for_pointer = */ 0);
144 obstack_1grow (mangle_obstack, 'E');
147 /* This mangles a field decl */
149 static void
150 mangle_field_decl (tree decl)
152 /* Mangle the name of the this the field belongs to */
153 mangle_record_type (DECL_CONTEXT (decl), /* for_pointer = */ 0);
155 /* Mangle the name of the field */
156 mangle_member_name (DECL_NAME (decl));
158 /* Terminate the mangled name */
159 obstack_1grow (mangle_obstack, 'E');
162 /* This mangles a method decl, first mangling its name and then all
163 its arguments. */
165 static void
166 mangle_method_decl (tree mdecl)
168 tree method_name = DECL_NAME (mdecl);
169 tree arglist;
171 /* Mangle the name of the type that contains mdecl */
172 mangle_record_type (DECL_CONTEXT (mdecl), /* for_pointer = */ 0);
174 /* Mangle the function name. There are two cases:
175 - mdecl is a constructor, use `C1' for its name, (denotes a
176 complete object constructor.)
177 - mdecl is not a constructor, standard mangling is performed.
178 We terminate the mangled function name with a `E'. */
179 if (ID_INIT_P (method_name))
180 obstack_grow (mangle_obstack, "C1", 2);
181 else
182 mangle_member_name (method_name);
183 obstack_1grow (mangle_obstack, 'E');
185 /* We mangled type.methodName. Now onto the arguments. */
186 arglist = TYPE_ARG_TYPES (TREE_TYPE (mdecl));
187 if (TREE_CODE (TREE_TYPE (mdecl)) == METHOD_TYPE)
188 arglist = TREE_CHAIN (arglist);
190 /* Output literal 'J' and mangle the return type IF not a
191 constructor. */
192 if (!ID_INIT_P (method_name))
194 obstack_1grow (mangle_obstack, 'J');
195 mangle_type(TREE_TYPE(TREE_TYPE(mdecl)));
198 /* No arguments is easy. We shortcut it. */
199 if (arglist == end_params_node)
200 obstack_1grow (mangle_obstack, 'v');
201 else
203 tree arg;
204 for (arg = arglist; arg != end_params_node; arg = TREE_CHAIN (arg))
205 mangle_type (TREE_VALUE (arg));
209 /* This mangles a CNI method for a local class. If the target supports
210 hidden aliases, then G++ will have generated one for us. It is the
211 responsibility of java_mark_class_local to check target support, since
212 we need to set DECL_VISIBILITY (or not) much earlier. */
214 static void
215 mangle_local_cni_method_decl (tree decl)
217 MANGLE_RAW_STRING ("GA");
218 mangle_method_decl (decl);
221 /* This mangles a member name, like a function name or a field
222 name. Handle cases were `name' is a C++ keyword. Return a nonzero
223 value if unicode encoding was required. */
225 static void
226 mangle_member_name (tree name)
228 append_gpp_mangled_name (IDENTIFIER_POINTER (name),
229 IDENTIFIER_LENGTH (name));
232 /* Append the mangled name of TYPE onto OBSTACK. */
234 static void
235 mangle_type (tree type)
237 switch (TREE_CODE (type))
239 char code;
240 case BOOLEAN_TYPE: code = 'b'; goto primitive;
241 case VOID_TYPE: code = 'v'; goto primitive;
242 case INTEGER_TYPE:
243 if (type == char_type_node || type == promoted_char_type_node)
245 code = 'w';
246 goto primitive;
248 /* Get the original type instead of the arguments promoted type.
249 Avoid symbol name clashes. Should call a function to do that.
250 FIXME. */
251 if (type == promoted_short_type_node)
252 type = short_type_node;
253 if (type == promoted_byte_type_node)
254 type = byte_type_node;
255 switch (TYPE_PRECISION (type))
257 case 8: code = 'c'; goto primitive;
258 case 16: code = 's'; goto primitive;
259 case 32: code = 'i'; goto primitive;
260 case 64: code = 'x'; goto primitive;
261 default: goto bad_type;
263 primitive:
264 obstack_1grow (mangle_obstack, code);
265 break;
267 case REAL_TYPE:
268 switch (TYPE_PRECISION (type))
270 case 32: code = 'f'; goto primitive;
271 case 64: code = 'd'; goto primitive;
272 default: goto bad_type;
274 case POINTER_TYPE:
275 if (TYPE_ARRAY_P (TREE_TYPE (type)))
276 mangle_array_type (type);
277 else
278 mangle_pointer_type (type);
279 break;
280 bad_type:
281 default:
282 gcc_unreachable ();
286 /* The compression table is a vector that keeps track of things we've
287 already seen, so they can be reused. For example, java.lang.Object
288 would generate three entries: two package names and a type. If
289 java.lang.String is presented next, the java.lang will be matched
290 against the first two entries (and kept for compression as S0_), and
291 type String would be added to the table. See mangle_record_type.
292 COMPRESSION_NEXT is the index to the location of the next insertion
293 of an element. */
295 static GTY(()) tree compression_table;
296 static int compression_next;
298 /* Find a POINTER_TYPE in the compression table. Use a special
299 function to match pointer entries and start from the end */
301 static int
302 find_compression_pointer_match (tree type)
304 int i;
306 for (i = compression_next-1; i >= 0; i--)
307 if (entry_match_pointer_p (type, i))
308 return i;
309 return -1;
312 /* Already recorder arrays are handled like pointer as they're always
313 associated with it. */
315 static int
316 find_compression_array_match (tree type)
318 return find_compression_pointer_match (type);
321 /* Match the table of type against STRING. */
323 static int
324 find_compression_array_template_match (tree string)
326 int i;
327 for (i = 0; i < compression_next; i++)
328 if (TREE_VEC_ELT (compression_table, i) == string)
329 return i;
330 return -1;
333 /* We go through the compression table and try to find a complete or
334 partial match. The function returns the compression table entry
335 that (eventually partially) matches TYPE. *NEXT_CURRENT can be set
336 to the rest of TYPE to be mangled. */
338 static int
339 find_compression_record_match (tree type, tree *next_current)
341 int i, match = -1;
342 tree current, saved_current = NULL_TREE;
344 current = TYPE_PACKAGE_LIST (type);
346 for (i = 0; i < compression_next; i++)
348 tree compression_entry = TREE_VEC_ELT (compression_table, i);
349 if (current && compression_entry == TREE_PURPOSE (current))
351 match = i;
352 saved_current = current;
353 current = TREE_CHAIN (current);
355 else
356 /* We don't want to match an element that appears in the middle
357 of a package name, so skip forward to the next complete type name.
358 IDENTIFIER_NODEs (except for a "6JArray") are partial package
359 names while RECORD_TYPEs represent complete type names. */
360 while (i < compression_next
361 && TREE_CODE (compression_entry) == IDENTIFIER_NODE
362 && compression_entry != atms)
363 compression_entry = TREE_VEC_ELT (compression_table, ++i);
366 if (!next_current)
367 return match;
369 /* If we have a match, set next_current to the item next to the last
370 matched value. */
371 if (match >= 0)
372 *next_current = TREE_CHAIN (saved_current);
373 /* We had no match: we'll have to start from the beginning. */
374 if (match < 0)
375 *next_current = TYPE_PACKAGE_LIST (type);
377 return match;
380 /* Mangle a record type. If a nonzero value is returned, it means
381 that a 'N' was emitted (so that a matching 'E' can be emitted if
382 necessary.) FOR_POINTER indicates that this element is for a pointer
383 symbol, meaning it was preceded by a 'P'. */
385 static int
386 mangle_record_type (tree type, int for_pointer)
388 tree current;
389 int match;
390 int nadded_p = 0;
391 int qualified;
393 /* Does this name have a package qualifier? */
394 qualified = QUALIFIED_P (DECL_NAME (TYPE_NAME (type)));
396 #define ADD_N() \
397 do { obstack_1grow (mangle_obstack, 'N'); nadded_p = 1; } while (0)
399 gcc_assert (TREE_CODE (type) == RECORD_TYPE);
401 if (!TYPE_PACKAGE_LIST (type))
402 set_type_package_list (type);
404 match = find_compression_record_match (type, &current);
405 if (match >= 0)
407 /* If we had a pointer, and there's more, we need to emit
408 'N' after 'P' (for_pointer tells us we already emitted it.) */
409 if (for_pointer && current)
410 ADD_N();
411 emit_compression_string (match);
413 while (current)
415 /* Add the new type to the table */
416 compression_table_add (TREE_PURPOSE (current));
417 /* Add 'N' if we never got a chance to, but only if we have a qualified
418 name. For non-pointer elements, the name is always qualified. */
419 if ((qualified || !for_pointer) && !nadded_p)
420 ADD_N();
421 /* Use the bare type name for the mangle. */
422 append_gpp_mangled_name (IDENTIFIER_POINTER (TREE_VALUE (current)),
423 IDENTIFIER_LENGTH (TREE_VALUE (current)));
424 current = TREE_CHAIN (current);
426 return nadded_p;
427 #undef ADD_N
430 /* Mangle a pointer type. There are two cases: the pointer is already
431 in the compression table: the compression is emitted sans 'P'
432 indicator. Otherwise, a 'P' is emitted and, depending on the type,
433 a partial compression or/plus the rest of the mangling. */
435 static void
436 mangle_pointer_type (tree type)
438 int match;
439 tree pointer_type;
441 /* Search for the type already in the compression table */
442 if ((match = find_compression_pointer_match (type)) >= 0)
444 emit_compression_string (match);
445 return;
448 /* This didn't work. We start by mangling the pointed-to type */
449 pointer_type = type;
450 type = TREE_TYPE (type);
451 gcc_assert (TREE_CODE (type) == RECORD_TYPE);
453 obstack_1grow (mangle_obstack, 'P');
454 if (mangle_record_type (type, /* for_pointer = */ 1))
455 obstack_1grow (mangle_obstack, 'E');
457 /* Don't forget to insert the pointer type in the table */
458 compression_table_add (pointer_type);
461 /* Mangle an array type. Search for an easy solution first, then go
462 through the process of finding out whether the bare array type or even
463 the template indicator were already used and compressed appropriately.
464 It handles pointers. */
466 static void
467 mangle_array_type (tree p_type)
469 tree type, elt_type;
470 int match;
472 type = TREE_TYPE (p_type);
473 gcc_assert (type);
475 elt_type = TYPE_ARRAY_ELEMENT (type);
477 /* We cache a bit of the Jarray <> mangle. */
478 if (!atms)
480 atms = get_identifier ("6JArray");
483 /* Maybe we have what we're looking for in the compression table. */
484 if ((match = find_compression_array_match (p_type)) >= 0)
486 emit_compression_string (match);
487 return;
490 /* We know for a fact that all arrays are pointers */
491 obstack_1grow (mangle_obstack, 'P');
492 /* Maybe we already have a Jarray<t> somewhere. PSx_ will be enough. */
493 if ((match = find_compression_record_match (type, NULL)) > 0)
495 emit_compression_string (match);
496 return;
499 /* Maybe we already have just JArray somewhere */
500 if ((match = find_compression_array_template_match (atms)) > 0)
501 emit_compression_string (match);
502 else
504 /* Start the template mangled name */
505 obstack_grow (mangle_obstack,
506 IDENTIFIER_POINTER (atms), IDENTIFIER_LENGTH (atms));
507 /* Insert in the compression table */
508 compression_table_add (atms);
511 /* Mangle Jarray <elt_type> */
512 obstack_1grow (mangle_obstack, 'I');
513 mangle_type (elt_type);
514 obstack_1grow (mangle_obstack, 'E');
516 /* Add `Jarray <elt_type>' and `Jarray <elt_type> *' to the table */
517 compression_table_add (type);
518 compression_table_add (p_type);
521 /* Write a substitution string for entry I. Substitution string starts a
522 -1 (encoded S_.) The base is 36, and the code shamelessly taken from
523 cp/mangle.c. */
525 static void
526 emit_compression_string (int i)
528 i -= 1; /* Adjust */
529 obstack_1grow (mangle_obstack, 'S');
530 if (i >= 0)
532 static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
533 unsigned HOST_WIDE_INT n;
534 unsigned HOST_WIDE_INT m=1;
535 /* How many digits for I in base 36? */
536 for (n = i; n >= 36; n /= 36, m *=36);
537 /* Write the digits out */
538 while (m > 0)
540 int digit = i / m;
541 obstack_1grow (mangle_obstack, digits [digit]);
542 i -= digit * m;
543 m /= 36;
546 obstack_1grow (mangle_obstack, '_');
549 /* If search the compression table at index I for a pointer type
550 equivalent to TYPE (meaning that after all the indirection, which
551 might all be unique, we find the same RECORD_TYPE.) */
553 static int
554 entry_match_pointer_p (tree type, int i)
556 tree t = TREE_VEC_ELT (compression_table, i);
558 while (TREE_CODE (type) == POINTER_TYPE
559 && TREE_CODE (t) == POINTER_TYPE)
561 t = TREE_TYPE (t);
562 type = TREE_TYPE (type);
564 return (TREE_CODE (type) == RECORD_TYPE
565 && TREE_CODE (t) == RECORD_TYPE
566 && t == type);
569 /* Go through all qualification of type and build a list of list node
570 elements containings as a purpose what should be used for a match and
571 inserted in the compression table; and as it value the raw name of the
572 part. The result is stored in TYPE_PACKAGE_LIST to be reused. */
574 static void
575 set_type_package_list (tree type)
577 int i;
578 const char *type_string = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
579 const char *ptr;
580 int qualifications;
581 tree list = NULL_TREE, elt;
583 for (ptr = type_string, qualifications = 0; *ptr; ptr++)
584 if (*ptr == '.')
585 qualifications += 1;
587 for (ptr = type_string, i = 0; i < qualifications; ptr++)
589 if (ptr [0] == '.')
591 tree const identifier
592 = get_identifier_with_length (type_string, ptr - type_string);
594 elt = build_tree_list (identifier, identifier);
595 TREE_CHAIN (elt) = list;
596 list = elt;
597 type_string = ptr+1;
598 i += 1;
602 elt = build_tree_list (type, get_identifier (type_string));
603 TREE_CHAIN (elt) = list;
604 list = elt;
605 TYPE_PACKAGE_LIST (type) = nreverse (list);
608 /* Add TYPE as the last element of the compression table. Resize the
609 compression table if necessary. */
611 static void
612 compression_table_add (tree type)
614 if (compression_next == TREE_VEC_LENGTH (compression_table))
616 tree new_table = make_tree_vec (2*compression_next);
617 int i;
619 for (i = 0; i < compression_next; i++)
620 TREE_VEC_ELT (new_table, i) = TREE_VEC_ELT (compression_table, i);
622 compression_table = new_table;
624 TREE_VEC_ELT (compression_table, compression_next++) = type;
627 /* Mangle an embedded resource file name. "_ZGr" is the prefix. A
628 '_' is prepended to the name so that names starting with a digit
629 can be demangled. The length and then the resulting name itself
630 are appended while escaping '$', '.', and '/' to: "$$", "$_", and
631 "$S". */
633 tree
634 java_mangle_resource_name (const char *name)
636 int len = strlen (name);
637 char *buf = (char *) alloca (2 * len + 1);
638 char *pos;
639 const unsigned char *w1 = (const unsigned char *) name;
640 const unsigned char *w2;
641 const unsigned char *limit = w1 + len;
643 pos = buf;
645 init_mangling ();
646 MANGLE_RAW_STRING ("Gr");
648 *pos++ = '_';
649 while (w1 < limit)
651 int ch;
652 w2 = w1;
653 ch = UTF8_GET (w1, limit);
654 gcc_assert (ch > 0);
655 switch (ch)
657 case '$':
658 *pos++ = '$';
659 *pos++ = '$';
660 break;
661 case '.':
662 *pos++ = '$';
663 *pos++ = '_';
664 break;
665 case '/':
666 *pos++ = '$';
667 *pos++ = 'S';
668 break;
669 default:
670 memcpy (pos, w2, w1 - w2);
671 pos += w1 - w2;
672 break;
675 append_gpp_mangled_name (buf, pos - buf);
677 return finish_mangling ();
680 /* Mangling initialization routine. */
682 static void
683 init_mangling (void)
685 if (!mangle_obstack)
687 mangle_obstack = &mangle_obstack_1;
688 gcc_obstack_init (mangle_obstack);
691 gcc_assert (compression_table == NULL);
692 compression_table = make_tree_vec (10);
694 /* Mangled name are to be suffixed */
695 MANGLE_RAW_STRING ("_Z");
698 /* Mangling finalization routine. The mangled name is returned as a
699 IDENTIFIER_NODE. */
701 static tree
702 finish_mangling (void)
704 tree result;
706 gcc_assert (compression_table);
708 compression_table = NULL_TREE;
709 compression_next = 0;
710 obstack_1grow (mangle_obstack, '\0');
711 result = get_identifier ((char *) obstack_base (mangle_obstack));
712 obstack_free (mangle_obstack, obstack_base (mangle_obstack));
714 return result;
717 #include "gt-java-mangle.h"