00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "config.h"
00029 #include "system.h"
00030 #include "jcf.h"
00031 #include "tree.h"
00032 #include "java-tree.h"
00033 #include "obstack.h"
00034 #include "toplev.h"
00035 #include "obstack.h"
00036 #include "ggc.h"
00037
00038 static void mangle_field_decl PARAMS ((tree));
00039 static void mangle_method_decl PARAMS ((tree));
00040
00041 static void mangle_type PARAMS ((tree));
00042 static void mangle_pointer_type PARAMS ((tree));
00043 static void mangle_array_type PARAMS ((tree));
00044 static int mangle_record_type PARAMS ((tree, int));
00045
00046 static int find_compression_pointer_match PARAMS ((tree));
00047 static int find_compression_array_match PARAMS ((tree));
00048 static int find_compression_record_match PARAMS ((tree, tree *));
00049 static int find_compression_array_template_match PARAMS ((tree));
00050
00051 static void set_type_package_list PARAMS ((tree));
00052 static int entry_match_pointer_p PARAMS ((tree, int));
00053 static void emit_compression_string PARAMS ((int));
00054
00055 static void init_mangling PARAMS ((struct obstack *));
00056 static tree finish_mangling PARAMS ((void));
00057 static void compression_table_add PARAMS ((tree));
00058
00059 static void mangle_member_name PARAMS ((tree));
00060
00061
00062
00063 struct obstack *mangle_obstack;
00064 #define MANGLE_RAW_STRING(S) \
00065 obstack_grow (mangle_obstack, (S), sizeof (S)-1)
00066
00067
00068
00069
00070 tree
00071 java_mangle_decl (obstack, decl)
00072 struct obstack *obstack;
00073 tree decl;
00074 {
00075 init_mangling (obstack);
00076 switch (TREE_CODE (decl))
00077 {
00078 case VAR_DECL:
00079 mangle_field_decl (decl);
00080 break;
00081 case FUNCTION_DECL:
00082 mangle_method_decl (decl);
00083 break;
00084 default:
00085 internal_error ("can't mangle %s", tree_code_name [TREE_CODE (decl)]);
00086 }
00087 return finish_mangling ();
00088 }
00089
00090 tree
00091 java_mangle_class_field (obstack, type)
00092 struct obstack *obstack;
00093 tree type;
00094 {
00095 init_mangling (obstack);
00096 mangle_record_type (type, 0);
00097 MANGLE_RAW_STRING ("6class$");
00098 obstack_1grow (mangle_obstack, 'E');
00099 return finish_mangling ();
00100 }
00101
00102 tree
00103 java_mangle_vtable (obstack, type)
00104 struct obstack *obstack;
00105 tree type;
00106 {
00107 init_mangling (obstack);
00108 MANGLE_RAW_STRING ("TV");
00109 mangle_record_type (type, 0);
00110 obstack_1grow (mangle_obstack, 'E');
00111 return finish_mangling ();
00112 }
00113
00114
00115
00116
00117
00118 static void
00119 mangle_field_decl (decl)
00120 tree decl;
00121 {
00122
00123 mangle_record_type (DECL_CONTEXT (decl), 0);
00124
00125
00126 mangle_member_name (DECL_NAME (decl));
00127
00128
00129 obstack_1grow (mangle_obstack, 'E');
00130 }
00131
00132
00133
00134
00135 static void
00136 mangle_method_decl (mdecl)
00137 tree mdecl;
00138 {
00139 tree method_name = DECL_NAME (mdecl);
00140 tree arglist;
00141
00142
00143 mangle_record_type (DECL_CONTEXT (mdecl), 0);
00144
00145
00146
00147
00148
00149
00150 if (ID_INIT_P (method_name))
00151 obstack_grow (mangle_obstack, "C1", 2);
00152 else
00153 mangle_member_name (method_name);
00154 obstack_1grow (mangle_obstack, 'E');
00155
00156
00157 arglist = TYPE_ARG_TYPES (TREE_TYPE (mdecl));
00158 if (TREE_CODE (TREE_TYPE (mdecl)) == METHOD_TYPE)
00159 arglist = TREE_CHAIN (arglist);
00160
00161
00162 if (arglist == end_params_node)
00163 obstack_1grow (mangle_obstack, 'v');
00164 else
00165 {
00166 tree arg;
00167 for (arg = arglist; arg != end_params_node; arg = TREE_CHAIN (arg))
00168 mangle_type (TREE_VALUE (arg));
00169 }
00170 }
00171
00172
00173
00174
00175
00176 static void
00177 mangle_member_name (name)
00178 tree name;
00179 {
00180 append_gpp_mangled_name (IDENTIFIER_POINTER (name),
00181 IDENTIFIER_LENGTH (name));
00182
00183
00184 if (cxx_keyword_p (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name)))
00185 obstack_1grow (mangle_obstack, '$');
00186 }
00187
00188
00189
00190 static void
00191 mangle_type (type)
00192 tree type;
00193 {
00194 switch (TREE_CODE (type))
00195 {
00196 char code;
00197 case BOOLEAN_TYPE: code = 'b'; goto primitive;
00198 case CHAR_TYPE: code = 'w'; goto primitive;
00199 case VOID_TYPE: code = 'v'; goto primitive;
00200 case INTEGER_TYPE:
00201
00202
00203
00204 if (type == promoted_short_type_node)
00205 type = short_type_node;
00206 if (type == promoted_byte_type_node)
00207 type = byte_type_node;
00208 switch (TYPE_PRECISION (type))
00209 {
00210 case 8: code = 'c'; goto primitive;
00211 case 16: code = 's'; goto primitive;
00212 case 32: code = 'i'; goto primitive;
00213 case 64: code = 'x'; goto primitive;
00214 default: goto bad_type;
00215 }
00216 primitive:
00217 obstack_1grow (mangle_obstack, code);
00218 break;
00219
00220 case REAL_TYPE:
00221 switch (TYPE_PRECISION (type))
00222 {
00223 case 32: code = 'f'; goto primitive;
00224 case 64: code = 'd'; goto primitive;
00225 default: goto bad_type;
00226 }
00227 case POINTER_TYPE:
00228 if (TYPE_ARRAY_P (TREE_TYPE (type)))
00229 mangle_array_type (type);
00230 else
00231 mangle_pointer_type (type);
00232 break;
00233 bad_type:
00234 default:
00235 abort ();
00236 }
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 static tree compression_table;
00249 static int compression_next;
00250
00251
00252
00253
00254 static int
00255 find_compression_pointer_match (type)
00256 tree type;
00257 {
00258 int i;
00259
00260 for (i = compression_next-1; i >= 0; i--)
00261 if (entry_match_pointer_p (type, i))
00262 return i;
00263 return -1;
00264 }
00265
00266
00267
00268
00269 static int
00270 find_compression_array_match (type)
00271 tree type;
00272 {
00273 return find_compression_pointer_match (type);
00274 }
00275
00276
00277
00278 static int
00279 find_compression_array_template_match (string)
00280 tree string;
00281 {
00282 int i;
00283 for (i = 0; i < compression_next; i++)
00284 if (TREE_VEC_ELT (compression_table, i) == string)
00285 return i;
00286 return -1;
00287 }
00288
00289
00290
00291
00292
00293
00294 static int
00295 find_compression_record_match (type, next_current)
00296 tree type;
00297 tree *next_current;
00298 {
00299 int i, match;
00300 tree current, saved_current = NULL_TREE;
00301
00302
00303
00304 for (current = TYPE_PACKAGE_LIST (type), i = 0, match = -1; current;
00305 current = TREE_CHAIN (current))
00306 {
00307 int j;
00308 for (j = i; j < compression_next; j++)
00309 if (TREE_VEC_ELT (compression_table, j) == TREE_PURPOSE (current))
00310 {
00311 match = i = j;
00312 saved_current = current;
00313 i++;
00314 break;
00315 }
00316 else
00317 {
00318
00319
00320
00321
00322 while (j < compression_next
00323 && TREE_CODE (TREE_VEC_ELT (compression_table, j)) ==
00324 IDENTIFIER_NODE)
00325 j++;
00326 }
00327 }
00328
00329 if (!next_current)
00330 return match;
00331
00332
00333
00334 if (match >= 0)
00335 *next_current = TREE_CHAIN (saved_current);
00336
00337 if (match < 0)
00338 *next_current = TYPE_PACKAGE_LIST (type);
00339
00340 return match;
00341 }
00342
00343
00344
00345
00346
00347
00348 static int
00349 mangle_record_type (type, for_pointer)
00350 tree type;
00351 int for_pointer;
00352 {
00353 tree current;
00354 int match;
00355 int nadded_p = 0;
00356 int qualified;
00357
00358
00359 qualified = QUALIFIED_P (DECL_NAME (TYPE_NAME (type)));
00360
00361 #define ADD_N() \
00362 do { obstack_1grow (mangle_obstack, 'N'); nadded_p = 1; } while (0)
00363
00364 if (TREE_CODE (type) != RECORD_TYPE)
00365 abort ();
00366
00367 if (!TYPE_PACKAGE_LIST (type))
00368 set_type_package_list (type);
00369
00370 match = find_compression_record_match (type, ¤t);
00371 if (match >= 0)
00372 {
00373
00374
00375 if (for_pointer && current)
00376 ADD_N();
00377 emit_compression_string (match);
00378 }
00379 while (current)
00380 {
00381
00382 compression_table_add (TREE_PURPOSE (current));
00383
00384
00385 if ((qualified || !for_pointer) && !nadded_p)
00386 ADD_N();
00387
00388 append_gpp_mangled_name (IDENTIFIER_POINTER (TREE_VALUE (current)),
00389 IDENTIFIER_LENGTH (TREE_VALUE (current)));
00390 current = TREE_CHAIN (current);
00391 }
00392 return nadded_p;
00393 #undef ADD_N
00394 }
00395
00396
00397
00398
00399
00400
00401 static void
00402 mangle_pointer_type (type)
00403 tree type;
00404 {
00405 int match;
00406 tree pointer_type;
00407
00408
00409 if ((match = find_compression_pointer_match (type)) >= 0)
00410 {
00411 emit_compression_string (match);
00412 return;
00413 }
00414
00415
00416 pointer_type = type;
00417 type = TREE_TYPE (type);
00418 if (TREE_CODE (type) != RECORD_TYPE)
00419 abort ();
00420
00421 obstack_1grow (mangle_obstack, 'P');
00422 if (mangle_record_type (type, 1))
00423 obstack_1grow (mangle_obstack, 'E');
00424
00425
00426 compression_table_add (pointer_type);
00427 }
00428
00429
00430
00431
00432
00433
00434 static void
00435 mangle_array_type (p_type)
00436 tree p_type;
00437 {
00438
00439 static tree atms = NULL_TREE;
00440 tree type, elt_type;
00441 int match;
00442
00443 type = TREE_TYPE (p_type);
00444 if (!type)
00445 abort ();
00446
00447 elt_type = TYPE_ARRAY_ELEMENT (type);
00448
00449
00450 if (!atms)
00451 {
00452 atms = get_identifier ("6JArray");
00453 ggc_add_tree_root (&atms, 1);
00454 }
00455
00456
00457 if ((match = find_compression_array_match (p_type)) >= 0)
00458 {
00459 emit_compression_string (match);
00460 return;
00461 }
00462
00463
00464 obstack_1grow (mangle_obstack, 'P');
00465
00466 if ((match = find_compression_record_match (type, NULL)) > 0)
00467 {
00468 emit_compression_string (match);
00469 return;
00470 }
00471
00472
00473 if ((match = find_compression_array_template_match (atms)) > 0)
00474 emit_compression_string (match);
00475 else
00476 {
00477
00478 obstack_grow (mangle_obstack,
00479 IDENTIFIER_POINTER (atms), IDENTIFIER_LENGTH (atms));
00480
00481 compression_table_add (atms);
00482 }
00483
00484
00485 obstack_1grow (mangle_obstack, 'I');
00486 mangle_type (elt_type);
00487 obstack_1grow (mangle_obstack, 'E');
00488
00489
00490 compression_table_add (type);
00491 compression_table_add (p_type);
00492 }
00493
00494
00495
00496
00497
00498 static void
00499 emit_compression_string (int i)
00500 {
00501 i -= 1;
00502 obstack_1grow (mangle_obstack, 'S');
00503 if (i >= 0)
00504 {
00505 static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
00506 unsigned HOST_WIDE_INT n;
00507 unsigned HOST_WIDE_INT m=1;
00508
00509 for (n = i; n >= 36; n /= 36, m *=36);
00510
00511 while (m > 0)
00512 {
00513 int digit = i / m;
00514 obstack_1grow (mangle_obstack, digits [digit]);
00515 i -= digit * m;
00516 m /= 36;
00517 }
00518 }
00519 obstack_1grow (mangle_obstack, '_');
00520 }
00521
00522
00523
00524
00525
00526 static int
00527 entry_match_pointer_p (type, i)
00528 tree type;
00529 int i;
00530 {
00531 tree t = TREE_VEC_ELT (compression_table, i);
00532
00533 while (TREE_CODE (type) == POINTER_TYPE
00534 && TREE_CODE (t) == POINTER_TYPE)
00535 {
00536 t = TREE_TYPE (t);
00537 type = TREE_TYPE (type);
00538 }
00539 return (TREE_CODE (type) == RECORD_TYPE
00540 && TREE_CODE (t) == RECORD_TYPE
00541 && t == type);
00542 }
00543
00544
00545
00546
00547
00548
00549 static void
00550 set_type_package_list (type)
00551 tree type;
00552 {
00553 int i;
00554 const char *type_string = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
00555 char *ptr;
00556 int qualifications;
00557 tree list = NULL_TREE, elt;
00558
00559 for (ptr = (char *)type_string, qualifications = 0; *ptr; ptr++)
00560 if (*ptr == '.')
00561 qualifications += 1;
00562
00563 for (ptr = (char *)type_string, i = 0; i < qualifications; ptr++)
00564 {
00565 if (ptr [0] == '.')
00566 {
00567 char c;
00568 tree identifier;
00569
00570
00571
00572 c = ptr [0];
00573 ptr [0] = '\0';
00574 identifier = get_identifier (type_string);
00575 ptr [0] = c;
00576 elt = build_tree_list (identifier, identifier);
00577 TREE_CHAIN (elt) = list;
00578 list = elt;
00579 type_string = ptr+1;
00580 i += 1;
00581 }
00582 }
00583
00584 elt = build_tree_list (type, get_identifier (type_string));
00585 TREE_CHAIN (elt) = list;
00586 list = elt;
00587 TYPE_PACKAGE_LIST (type) = nreverse (list);
00588 }
00589
00590
00591
00592
00593 static void
00594 compression_table_add (type)
00595 tree type;
00596 {
00597 if (compression_next == TREE_VEC_LENGTH (compression_table))
00598 {
00599 tree new = make_tree_vec (2*compression_next);
00600 int i;
00601
00602 for (i = 0; i < compression_next; i++)
00603 TREE_VEC_ELT (new, i) = TREE_VEC_ELT (compression_table, i);
00604
00605 ggc_del_root (&compression_table);
00606 compression_table = new;
00607 ggc_add_tree_root (&compression_table, 1);
00608 }
00609 TREE_VEC_ELT (compression_table, compression_next++) = type;
00610 }
00611
00612
00613
00614 static void
00615 init_mangling (obstack)
00616 struct obstack *obstack;
00617 {
00618 mangle_obstack = obstack;
00619 if (!compression_table)
00620 compression_table = make_tree_vec (10);
00621 else
00622
00623 abort ();
00624
00625
00626 obstack_grow (mangle_obstack, "_Z", 2);
00627
00628
00629 ggc_add_tree_root (&compression_table, 1);
00630 }
00631
00632
00633
00634
00635 static tree
00636 finish_mangling ()
00637 {
00638 tree result;
00639
00640 if (!compression_table)
00641
00642 abort ();
00643
00644 ggc_del_root (&compression_table);
00645 compression_table = NULL_TREE;
00646 compression_next = 0;
00647 obstack_1grow (mangle_obstack, '\0');
00648 result = get_identifier (obstack_base (mangle_obstack));
00649 obstack_free (mangle_obstack, obstack_base (mangle_obstack));
00650 #if 0
00651 printf ("// %s\n", IDENTIFIER_POINTER (result));
00652 #endif
00653 return result;
00654 }