]>
Commit | Line | Data |
---|---|---|
e04a16fb AG |
1 | /* Functions related to mangling class names for the GNU compiler |
2 | for the Java(TM) language. | |
dc08e603 | 3 | Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. |
e04a16fb AG |
4 | |
5 | This file is part of GNU CC. | |
6 | ||
7 | GNU CC 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 2, or (at your option) | |
10 | any later version. | |
11 | ||
12 | GNU CC 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. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with GNU CC; see the file COPYING. If not, write to | |
19 | the Free Software Foundation, 59 Temple Place - Suite 330, | |
20 | Boston, MA 02111-1307, USA. | |
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 | ||
e04a16fb | 28 | #include "config.h" |
1f43f4b4 | 29 | #include "system.h" |
4977bab6 ZW |
30 | #include "coretypes.h" |
31 | #include "tm.h" | |
e04a16fb | 32 | #include "jcf.h" |
4bcde32e KG |
33 | #include "tree.h" |
34 | #include "java-tree.h" | |
e04a16fb | 35 | #include "obstack.h" |
d4476be2 | 36 | #include "toplev.h" |
dc08e603 APB |
37 | #include "obstack.h" |
38 | #include "ggc.h" | |
39 | ||
40 | static void mangle_field_decl PARAMS ((tree)); | |
41 | static void mangle_method_decl PARAMS ((tree)); | |
42 | ||
43 | static void mangle_type PARAMS ((tree)); | |
44 | static void mangle_pointer_type PARAMS ((tree)); | |
45 | static void mangle_array_type PARAMS ((tree)); | |
46 | static int mangle_record_type PARAMS ((tree, int)); | |
47 | ||
48 | static int find_compression_pointer_match PARAMS ((tree)); | |
49 | static int find_compression_array_match PARAMS ((tree)); | |
50 | static int find_compression_record_match PARAMS ((tree, tree *)); | |
51 | static int find_compression_array_template_match PARAMS ((tree)); | |
52 | ||
53 | static void set_type_package_list PARAMS ((tree)); | |
54 | static int entry_match_pointer_p PARAMS ((tree, int)); | |
55 | static void emit_compression_string PARAMS ((int)); | |
56 | ||
57 | static void init_mangling PARAMS ((struct obstack *)); | |
58 | static tree finish_mangling PARAMS ((void)); | |
59 | static void compression_table_add PARAMS ((tree)); | |
60 | ||
1b43b6be | 61 | static void mangle_member_name PARAMS ((tree)); |
dc08e603 APB |
62 | |
63 | /* We use an incoming obstack, always to be provided to the interface | |
64 | functions. */ | |
65 | struct obstack *mangle_obstack; | |
66 | #define MANGLE_RAW_STRING(S) \ | |
67 | obstack_grow (mangle_obstack, (S), sizeof (S)-1) | |
68 | ||
69 | /* This is the mangling interface: a decl, a class field (.class) and | |
70 | the vtable. */ | |
71 | ||
72 | tree | |
73 | java_mangle_decl (obstack, decl) | |
74 | struct obstack *obstack; | |
75 | tree decl; | |
76 | { | |
77 | init_mangling (obstack); | |
78 | switch (TREE_CODE (decl)) | |
79 | { | |
80 | case VAR_DECL: | |
81 | mangle_field_decl (decl); | |
82 | break; | |
83 | case FUNCTION_DECL: | |
84 | mangle_method_decl (decl); | |
85 | break; | |
86 | default: | |
c725bd79 | 87 | internal_error ("can't mangle %s", tree_code_name [TREE_CODE (decl)]); |
dc08e603 APB |
88 | } |
89 | return finish_mangling (); | |
90 | } | |
91 | ||
92 | tree | |
93 | java_mangle_class_field (obstack, type) | |
94 | struct obstack *obstack; | |
95 | tree type; | |
96 | { | |
97 | init_mangling (obstack); | |
551bf03c | 98 | mangle_record_type (type, /* for_pointer = */ 0); |
dc08e603 APB |
99 | MANGLE_RAW_STRING ("6class$"); |
100 | obstack_1grow (mangle_obstack, 'E'); | |
101 | return finish_mangling (); | |
102 | } | |
103 | ||
104 | tree | |
105 | java_mangle_vtable (obstack, type) | |
106 | struct obstack *obstack; | |
107 | tree type; | |
108 | { | |
109 | init_mangling (obstack); | |
110 | MANGLE_RAW_STRING ("TV"); | |
551bf03c | 111 | mangle_record_type (type, /* for_pointer = */ 0); |
dc08e603 APB |
112 | obstack_1grow (mangle_obstack, 'E'); |
113 | return finish_mangling (); | |
114 | } | |
115 | ||
116 | /* Beginning of the helper functions */ | |
117 | ||
118 | /* This mangles a field decl */ | |
119 | ||
120 | static void | |
121 | mangle_field_decl (decl) | |
122 | tree decl; | |
123 | { | |
dc08e603 | 124 | /* Mangle the name of the this the field belongs to */ |
551bf03c | 125 | mangle_record_type (DECL_CONTEXT (decl), /* for_pointer = */ 0); |
dc08e603 APB |
126 | |
127 | /* Mangle the name of the field */ | |
1b43b6be | 128 | mangle_member_name (DECL_NAME (decl)); |
dc08e603 APB |
129 | |
130 | /* Terminate the mangled name */ | |
131 | obstack_1grow (mangle_obstack, 'E'); | |
dc08e603 APB |
132 | } |
133 | ||
134 | /* This mangles a method decl, first mangling its name and then all | |
135 | its arguments. */ | |
136 | ||
137 | static void | |
138 | mangle_method_decl (mdecl) | |
139 | tree mdecl; | |
140 | { | |
141 | tree method_name = DECL_NAME (mdecl); | |
142 | tree arglist; | |
dc08e603 APB |
143 | |
144 | /* Mangle the name of the type that contains mdecl */ | |
551bf03c | 145 | mangle_record_type (DECL_CONTEXT (mdecl), /* for_pointer = */ 0); |
dc08e603 | 146 | |
2c5187c5 | 147 | /* Mangle the function name. There are two cases: |
dc08e603 APB |
148 | - mdecl is a constructor, use `C1' for its name, (denotes a |
149 | complete object constructor.) | |
150 | - mdecl is not a constructor, standard mangling is performed. | |
151 | We terminate the mangled function name with a `E'. */ | |
152 | if (ID_INIT_P (method_name)) | |
2c5187c5 | 153 | obstack_grow (mangle_obstack, "C1", 2); |
dc08e603 | 154 | else |
1b43b6be | 155 | mangle_member_name (method_name); |
dc08e603 APB |
156 | obstack_1grow (mangle_obstack, 'E'); |
157 | ||
158 | /* We mangled type.methodName. Now onto the arguments. */ | |
159 | arglist = TYPE_ARG_TYPES (TREE_TYPE (mdecl)); | |
160 | if (TREE_CODE (TREE_TYPE (mdecl)) == METHOD_TYPE) | |
161 | arglist = TREE_CHAIN (arglist); | |
162 | ||
163 | /* No arguments is easy. We shortcut it. */ | |
164 | if (arglist == end_params_node) | |
165 | obstack_1grow (mangle_obstack, 'v'); | |
166 | else | |
167 | { | |
168 | tree arg; | |
169 | for (arg = arglist; arg != end_params_node; arg = TREE_CHAIN (arg)) | |
170 | mangle_type (TREE_VALUE (arg)); | |
171 | } | |
dc08e603 APB |
172 | } |
173 | ||
174 | /* This mangles a member name, like a function name or a field | |
ee142fe7 | 175 | name. Handle cases were `name' is a C++ keyword. Return a nonzero |
dc08e603 APB |
176 | value if unicode encoding was required. */ |
177 | ||
1b43b6be | 178 | static void |
dc08e603 APB |
179 | mangle_member_name (name) |
180 | tree name; | |
181 | { | |
1b43b6be APB |
182 | append_gpp_mangled_name (IDENTIFIER_POINTER (name), |
183 | IDENTIFIER_LENGTH (name)); | |
dc08e603 | 184 | |
de4984af | 185 | /* If NAME happens to be a C++ keyword, add `$'. */ |
dc08e603 | 186 | if (cxx_keyword_p (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name))) |
de4984af | 187 | obstack_1grow (mangle_obstack, '$'); |
e04a16fb AG |
188 | } |
189 | ||
dc08e603 | 190 | /* Append the mangled name of TYPE onto OBSTACK. */ |
e04a16fb | 191 | |
dc08e603 APB |
192 | static void |
193 | mangle_type (type) | |
194 | tree type; | |
195 | { | |
196 | switch (TREE_CODE (type)) | |
197 | { | |
198 | char code; | |
199 | case BOOLEAN_TYPE: code = 'b'; goto primitive; | |
200 | case CHAR_TYPE: code = 'w'; goto primitive; | |
201 | case VOID_TYPE: code = 'v'; goto primitive; | |
202 | case INTEGER_TYPE: | |
203 | /* Get the original type instead of the arguments promoted type. | |
204 | Avoid symbol name clashes. Should call a function to do that. | |
205 | FIXME. */ | |
206 | if (type == promoted_short_type_node) | |
207 | type = short_type_node; | |
208 | if (type == promoted_byte_type_node) | |
209 | type = byte_type_node; | |
210 | switch (TYPE_PRECISION (type)) | |
211 | { | |
212 | case 8: code = 'c'; goto primitive; | |
213 | case 16: code = 's'; goto primitive; | |
214 | case 32: code = 'i'; goto primitive; | |
215 | case 64: code = 'x'; goto primitive; | |
216 | default: goto bad_type; | |
217 | } | |
218 | primitive: | |
219 | obstack_1grow (mangle_obstack, code); | |
220 | break; | |
221 | ||
222 | case REAL_TYPE: | |
223 | switch (TYPE_PRECISION (type)) | |
224 | { | |
225 | case 32: code = 'f'; goto primitive; | |
226 | case 64: code = 'd'; goto primitive; | |
227 | default: goto bad_type; | |
228 | } | |
229 | case POINTER_TYPE: | |
230 | if (TYPE_ARRAY_P (TREE_TYPE (type))) | |
231 | mangle_array_type (type); | |
232 | else | |
233 | mangle_pointer_type (type); | |
234 | break; | |
235 | bad_type: | |
236 | default: | |
400500c4 | 237 | abort (); |
dc08e603 APB |
238 | } |
239 | } | |
240 | ||
241 | /* The compression table is a vector that keeps track of things we've | |
242 | already seen, so they can be reused. For example, java.lang.Object | |
98f705b9 | 243 | would generate three entries: two package names and a type. If |
dc08e603 APB |
244 | java.lang.String is presented next, the java.lang will be matched |
245 | against the first two entries (and kept for compression as S_0), and | |
246 | type String would be added to the table. See mangle_record_type. | |
247 | COMPRESSION_NEXT is the index to the location of the next insertion | |
248 | of an element. */ | |
249 | ||
e2500fed | 250 | static GTY(()) tree compression_table; |
dc08e603 APB |
251 | static int compression_next; |
252 | ||
253 | /* Find a POINTER_TYPE in the compression table. Use a special | |
254 | function to match pointer entries and start from the end */ | |
255 | ||
256 | static int | |
257 | find_compression_pointer_match (type) | |
258 | tree type; | |
259 | { | |
260 | int i; | |
261 | ||
262 | for (i = compression_next-1; i >= 0; i--) | |
263 | if (entry_match_pointer_p (type, i)) | |
264 | return i; | |
265 | return -1; | |
266 | } | |
267 | ||
268 | /* Already recorder arrays are handled like pointer as they're always | |
269 | associated with it. */ | |
270 | ||
271 | static int | |
272 | find_compression_array_match (type) | |
273 | tree type; | |
274 | { | |
275 | return find_compression_pointer_match (type); | |
276 | } | |
277 | ||
278 | /* Match the table of type against STRING. */ | |
279 | ||
280 | static int | |
281 | find_compression_array_template_match (string) | |
282 | tree string; | |
283 | { | |
284 | int i; | |
285 | for (i = 0; i < compression_next; i++) | |
286 | if (TREE_VEC_ELT (compression_table, i) == string) | |
287 | return i; | |
288 | return -1; | |
289 | } | |
290 | ||
291 | /* We go through the compression table and try to find a complete or | |
292 | partial match. The function returns the compression table entry | |
293 | that (evenutally partially) matches TYPE. *NEXT_CURRENT can be set | |
294 | to the rest of TYPE to be mangled. */ | |
295 | ||
296 | static int | |
297 | find_compression_record_match (type, next_current) | |
298 | tree type; | |
299 | tree *next_current; | |
e04a16fb | 300 | { |
dc08e603 | 301 | int i, match; |
962584ea | 302 | tree current, saved_current = NULL_TREE; |
e04a16fb | 303 | |
dc08e603 APB |
304 | /* Search from the beginning for something that matches TYPE, even |
305 | partially. */ | |
306 | for (current = TYPE_PACKAGE_LIST (type), i = 0, match = -1; current; | |
307 | current = TREE_CHAIN (current)) | |
e04a16fb | 308 | { |
dc08e603 APB |
309 | int j; |
310 | for (j = i; j < compression_next; j++) | |
311 | if (TREE_VEC_ELT (compression_table, j) == TREE_PURPOSE (current)) | |
312 | { | |
313 | match = i = j; | |
314 | saved_current = current; | |
2b472f91 | 315 | i++; |
dc08e603 APB |
316 | break; |
317 | } | |
2b472f91 BM |
318 | else |
319 | { | |
320 | /* We don't want to match an element that appears in the middle | |
321 | of a package name, so skip forward to the next complete type name. | |
322 | IDENTIFIER_NODEs are partial package names while RECORD_TYPEs | |
323 | represent complete type names. */ | |
324 | while (j < compression_next | |
325 | && TREE_CODE (TREE_VEC_ELT (compression_table, j)) == | |
326 | IDENTIFIER_NODE) | |
327 | j++; | |
328 | } | |
dc08e603 APB |
329 | } |
330 | ||
331 | if (!next_current) | |
332 | return match; | |
333 | ||
334 | /* If we have a match, set next_current to the item next to the last | |
335 | matched value. */ | |
336 | if (match >= 0) | |
337 | *next_current = TREE_CHAIN (saved_current); | |
338 | /* We had no match: we'll have to start from the beginning. */ | |
339 | if (match < 0) | |
340 | *next_current = TYPE_PACKAGE_LIST (type); | |
341 | ||
342 | return match; | |
343 | } | |
344 | ||
ee142fe7 | 345 | /* Mangle a record type. If a nonzero value is returned, it means |
dc08e603 | 346 | that a 'N' was emitted (so that a matching 'E' can be emitted if |
551bf03c BM |
347 | necessary.) FOR_POINTER indicates that this element is for a pointer |
348 | symbol, meaning it was preceded by a 'P'. */ | |
dc08e603 APB |
349 | |
350 | static int | |
551bf03c | 351 | mangle_record_type (type, for_pointer) |
dc08e603 | 352 | tree type; |
551bf03c | 353 | int for_pointer; |
dc08e603 APB |
354 | { |
355 | tree current; | |
356 | int match; | |
357 | int nadded_p = 0; | |
551bf03c BM |
358 | int qualified; |
359 | ||
360 | /* Does this name have a package qualifier? */ | |
361 | qualified = QUALIFIED_P (DECL_NAME (TYPE_NAME (type))); | |
dc08e603 APB |
362 | |
363 | #define ADD_N() \ | |
364 | do { obstack_1grow (mangle_obstack, 'N'); nadded_p = 1; } while (0) | |
365 | ||
366 | if (TREE_CODE (type) != RECORD_TYPE) | |
400500c4 | 367 | abort (); |
dc08e603 APB |
368 | |
369 | if (!TYPE_PACKAGE_LIST (type)) | |
370 | set_type_package_list (type); | |
371 | ||
372 | match = find_compression_record_match (type, ¤t); | |
373 | if (match >= 0) | |
374 | { | |
375 | /* If we had a pointer, and there's more, we need to emit | |
551bf03c BM |
376 | 'N' after 'P' (for_pointer tells us we already emitted it.) */ |
377 | if (for_pointer && current) | |
dc08e603 APB |
378 | ADD_N(); |
379 | emit_compression_string (match); | |
e04a16fb | 380 | } |
dc08e603 | 381 | while (current) |
e04a16fb | 382 | { |
dc08e603 APB |
383 | /* Add the new type to the table */ |
384 | compression_table_add (TREE_PURPOSE (current)); | |
551bf03c BM |
385 | /* Add 'N' if we never got a chance to, but only if we have a qualified |
386 | name. For non-pointer elements, the name is always qualified. */ | |
387 | if ((qualified || !for_pointer) && !nadded_p) | |
dc08e603 APB |
388 | ADD_N(); |
389 | /* Use the bare type name for the mangle. */ | |
390 | append_gpp_mangled_name (IDENTIFIER_POINTER (TREE_VALUE (current)), | |
391 | IDENTIFIER_LENGTH (TREE_VALUE (current))); | |
392 | current = TREE_CHAIN (current); | |
393 | } | |
394 | return nadded_p; | |
395 | #undef ADD_N | |
396 | } | |
397 | ||
398 | /* Mangle a pointer type. There are two cases: the pointer is already | |
399 | in the compression table: the compression is emited sans 'P' | |
400 | indicator. Otherwise, a 'P' is emitted and, depending on the type, | |
401 | a partial compression or/plus the rest of the mangling. */ | |
402 | ||
403 | static void | |
404 | mangle_pointer_type (type) | |
405 | tree type; | |
406 | { | |
407 | int match; | |
408 | tree pointer_type; | |
409 | ||
410 | /* Search for the type already in the compression table */ | |
411 | if ((match = find_compression_pointer_match (type)) >= 0) | |
412 | { | |
413 | emit_compression_string (match); | |
414 | return; | |
e04a16fb | 415 | } |
dc08e603 APB |
416 | |
417 | /* This didn't work. We start by mangling the pointed-to type */ | |
418 | pointer_type = type; | |
419 | type = TREE_TYPE (type); | |
420 | if (TREE_CODE (type) != RECORD_TYPE) | |
400500c4 | 421 | abort (); |
dc08e603 APB |
422 | |
423 | obstack_1grow (mangle_obstack, 'P'); | |
424 | if (mangle_record_type (type, /* for_pointer = */ 1)) | |
425 | obstack_1grow (mangle_obstack, 'E'); | |
426 | ||
427 | /* Don't forget to insert the pointer type in the table */ | |
428 | compression_table_add (pointer_type); | |
429 | } | |
430 | ||
431 | /* Mangle an array type. Search for an easy solution first, then go | |
432 | through the process of finding out whether the bare array type or even | |
433 | the template indicator where already used an compress appropriately. | |
434 | It handles pointers. */ | |
435 | ||
e2500fed GK |
436 | /* atms: array template mangled string. */ |
437 | static GTY(()) tree atms; | |
dc08e603 APB |
438 | static void |
439 | mangle_array_type (p_type) | |
440 | tree p_type; | |
441 | { | |
dc08e603 APB |
442 | tree type, elt_type; |
443 | int match; | |
444 | ||
445 | type = TREE_TYPE (p_type); | |
446 | if (!type) | |
400500c4 RK |
447 | abort (); |
448 | ||
dc08e603 APB |
449 | elt_type = TYPE_ARRAY_ELEMENT (type); |
450 | ||
451 | /* We cache a bit of the Jarray <> mangle. */ | |
452 | if (!atms) | |
453 | { | |
454 | atms = get_identifier ("6JArray"); | |
dc08e603 APB |
455 | } |
456 | ||
457 | /* Maybe we have what we're looking in the compression table. */ | |
458 | if ((match = find_compression_array_match (p_type)) >= 0) | |
459 | { | |
460 | emit_compression_string (match); | |
461 | return; | |
462 | } | |
463 | ||
464 | /* We know for a fact that all arrays are pointers */ | |
465 | obstack_1grow (mangle_obstack, 'P'); | |
466 | /* Maybe we already have a Jarray<t> somewhere. PSx_ will be enough. */ | |
467 | if ((match = find_compression_record_match (type, NULL)) > 0) | |
468 | { | |
469 | emit_compression_string (match); | |
470 | return; | |
471 | } | |
472 | ||
473 | /* Maybe we already have just JArray somewhere */ | |
474 | if ((match = find_compression_array_template_match (atms)) > 0) | |
475 | emit_compression_string (match); | |
476 | else | |
e04a16fb | 477 | { |
dc08e603 APB |
478 | /* Start the template mangled name */ |
479 | obstack_grow (mangle_obstack, | |
480 | IDENTIFIER_POINTER (atms), IDENTIFIER_LENGTH (atms)); | |
481 | /* Insert in the compression table */ | |
482 | compression_table_add (atms); | |
483 | } | |
484 | ||
485 | /* Mangle Jarray <elt_type> */ | |
486 | obstack_1grow (mangle_obstack, 'I'); | |
487 | mangle_type (elt_type); | |
488 | obstack_1grow (mangle_obstack, 'E'); | |
489 | ||
490 | /* Add `Jarray <elt_type>' and `Jarray <elt_type> *' to the table */ | |
491 | compression_table_add (type); | |
492 | compression_table_add (p_type); | |
493 | } | |
494 | ||
495 | /* Write a substition string for entry I. Substitution string starts a | |
496 | -1 (encoded S_.) The base is 36, and the code shamlessly taken from | |
497 | cp/mangle.c. */ | |
498 | ||
499 | static void | |
500 | emit_compression_string (int i) | |
501 | { | |
502 | i -= 1; /* Adjust */ | |
503 | obstack_1grow (mangle_obstack, 'S'); | |
504 | if (i >= 0) | |
505 | { | |
506 | static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
507 | unsigned HOST_WIDE_INT n; | |
508 | unsigned HOST_WIDE_INT m=1; | |
509 | /* How many digits for I in base 36? */ | |
510 | for (n = i; n >= 36; n /= 36, m *=36); | |
511 | /* Write the digits out */ | |
512 | while (m > 0) | |
e04a16fb | 513 | { |
dc08e603 APB |
514 | int digit = i / m; |
515 | obstack_1grow (mangle_obstack, digits [digit]); | |
516 | i -= digit * m; | |
517 | m /= 36; | |
518 | } | |
519 | } | |
520 | obstack_1grow (mangle_obstack, '_'); | |
521 | } | |
522 | ||
523 | /* If search the compression table at index I for a pointer type | |
524 | equivalent to TYPE (meaning that after all the indirection, which | |
525 | might all be unique, we find the same RECORD_TYPE.) */ | |
526 | ||
527 | static int | |
528 | entry_match_pointer_p (type, i) | |
529 | tree type; | |
530 | int i; | |
531 | { | |
532 | tree t = TREE_VEC_ELT (compression_table, i); | |
533 | ||
534 | while (TREE_CODE (type) == POINTER_TYPE | |
535 | && TREE_CODE (t) == POINTER_TYPE) | |
536 | { | |
537 | t = TREE_TYPE (t); | |
538 | type = TREE_TYPE (type); | |
539 | } | |
540 | return (TREE_CODE (type) == RECORD_TYPE | |
541 | && TREE_CODE (t) == RECORD_TYPE | |
542 | && t == type); | |
543 | } | |
544 | ||
545 | /* Go through all qualification of type and build a list of list node | |
546 | elements containings as a purpose what should be used for a match and | |
547 | inserted in the compression table; and as it value the raw name of the | |
548 | part. The result is stored in TYPE_PACKAGE_LIST to be reused. */ | |
549 | ||
550 | static void | |
551 | set_type_package_list (type) | |
552 | tree type; | |
553 | { | |
554 | int i; | |
555 | const char *type_string = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); | |
556 | char *ptr; | |
557 | int qualifications; | |
558 | tree list = NULL_TREE, elt; | |
559 | ||
560 | for (ptr = (char *)type_string, qualifications = 0; *ptr; ptr++) | |
561 | if (*ptr == '.') | |
562 | qualifications += 1; | |
563 | ||
564 | for (ptr = (char *)type_string, i = 0; i < qualifications; ptr++) | |
565 | { | |
566 | if (ptr [0] == '.') | |
567 | { | |
568 | char c; | |
569 | tree identifier; | |
570 | ||
571 | /* Can't use an obstack, we're already using it to | |
572 | accumulate the mangling. */ | |
573 | c = ptr [0]; | |
574 | ptr [0] = '\0'; | |
575 | identifier = get_identifier (type_string); | |
576 | ptr [0] = c; | |
577 | elt = build_tree_list (identifier, identifier); | |
578 | TREE_CHAIN (elt) = list; | |
579 | list = elt; | |
580 | type_string = ptr+1; | |
581 | i += 1; | |
e04a16fb AG |
582 | } |
583 | } | |
dc08e603 APB |
584 | |
585 | elt = build_tree_list (type, get_identifier (type_string)); | |
586 | TREE_CHAIN (elt) = list; | |
587 | list = elt; | |
588 | TYPE_PACKAGE_LIST (type) = nreverse (list); | |
589 | } | |
590 | ||
591 | /* Add TYPE as the last element of the compression table. Resize the | |
592 | compression table if necessary. */ | |
593 | ||
594 | static void | |
595 | compression_table_add (type) | |
596 | tree type; | |
597 | { | |
598 | if (compression_next == TREE_VEC_LENGTH (compression_table)) | |
599 | { | |
600 | tree new = make_tree_vec (2*compression_next); | |
601 | int i; | |
602 | ||
603 | for (i = 0; i < compression_next; i++) | |
604 | TREE_VEC_ELT (new, i) = TREE_VEC_ELT (compression_table, i); | |
605 | ||
dc08e603 | 606 | compression_table = new; |
dc08e603 APB |
607 | } |
608 | TREE_VEC_ELT (compression_table, compression_next++) = type; | |
609 | } | |
610 | ||
611 | /* Mangling initialization routine. */ | |
612 | ||
613 | static void | |
614 | init_mangling (obstack) | |
615 | struct obstack *obstack; | |
616 | { | |
617 | mangle_obstack = obstack; | |
618 | if (!compression_table) | |
619 | compression_table = make_tree_vec (10); | |
620 | else | |
400500c4 RK |
621 | /* Mangling already in progress. */ |
622 | abort (); | |
dc08e603 APB |
623 | |
624 | /* Mangled name are to be suffixed */ | |
625 | obstack_grow (mangle_obstack, "_Z", 2); | |
dc08e603 APB |
626 | } |
627 | ||
628 | /* Mangling finalization routine. The mangled name is returned as a | |
629 | IDENTIFIER_NODE. */ | |
630 | ||
631 | static tree | |
632 | finish_mangling () | |
633 | { | |
634 | tree result; | |
635 | ||
636 | if (!compression_table) | |
400500c4 RK |
637 | /* Mangling already finished. */ |
638 | abort (); | |
dc08e603 | 639 | |
dc08e603 APB |
640 | compression_table = NULL_TREE; |
641 | compression_next = 0; | |
642 | obstack_1grow (mangle_obstack, '\0'); | |
643 | result = get_identifier (obstack_base (mangle_obstack)); | |
644 | obstack_free (mangle_obstack, obstack_base (mangle_obstack)); | |
645 | #if 0 | |
646 | printf ("// %s\n", IDENTIFIER_POINTER (result)); | |
647 | #endif | |
648 | return result; | |
e04a16fb | 649 | } |
e2500fed GK |
650 | |
651 | #include "gt-java-mangle.h" |