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
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #include "config.h"
00055 #include "system.h"
00056 #include "tree.h"
00057 #include "tm_p.h"
00058 #include "cp-tree.h"
00059 #include "real.h"
00060 #include "obstack.h"
00061 #include "toplev.h"
00062 #include "varray.h"
00063 #include "ggc.h"
00064
00065
00066
00067
00068 #ifndef DEBUG_MANGLE
00069 #define DEBUG_MANGLE 0
00070 #endif
00071
00072
00073 #if DEBUG_MANGLE
00074 # define MANGLE_TRACE(FN, INPUT) \
00075 fprintf (stderr, " %-24s: %-24s\n", (FN), (INPUT))
00076 # define MANGLE_TRACE_TREE(FN, NODE) \
00077 fprintf (stderr, " %-24s: %-24s (%p)\n", \
00078 (FN), tree_code_name[TREE_CODE (NODE)], (void *) (NODE))
00079 #else
00080 # define MANGLE_TRACE(FN, INPUT)
00081 # define MANGLE_TRACE_TREE(FN, NODE)
00082 #endif
00083
00084
00085
00086
00087
00088
00089 #define CLASSTYPE_TEMPLATE_ID_P(NODE) \
00090 (TYPE_LANG_SPECIFIC (NODE) != NULL \
00091 && (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM \
00092 || (CLASSTYPE_TEMPLATE_INFO (NODE) != NULL \
00093 && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE))))))
00094
00095
00096 static struct globals
00097 {
00098
00099 struct obstack name_obstack;
00100
00101
00102
00103 varray_type substitutions;
00104
00105
00106 tree entity;
00107
00108
00109
00110 bool need_abi_warning;
00111 } G;
00112
00113
00114
00115 typedef enum
00116 {
00117 SUBID_ALLOCATOR,
00118 SUBID_BASIC_STRING,
00119 SUBID_CHAR_TRAITS,
00120 SUBID_BASIC_ISTREAM,
00121 SUBID_BASIC_OSTREAM,
00122 SUBID_BASIC_IOSTREAM,
00123 SUBID_MAX
00124 }
00125 substitution_identifier_index_t;
00126
00127
00128
00129 static tree subst_identifiers[SUBID_MAX];
00130
00131
00132
00133 static const char
00134 integer_type_codes[itk_none] =
00135 {
00136 'c',
00137 'a',
00138 'h',
00139 's',
00140 't',
00141 'i',
00142 'j',
00143 'l',
00144 'm',
00145 'x',
00146 'y'
00147 };
00148
00149 static int decl_is_template_id PARAMS ((tree, tree*));
00150
00151
00152
00153 static inline tree canonicalize_for_substitution PARAMS ((tree));
00154 static void add_substitution PARAMS ((tree));
00155 static inline int is_std_substitution PARAMS ((tree, substitution_identifier_index_t));
00156 static inline int is_std_substitution_char PARAMS ((tree, substitution_identifier_index_t));
00157 static int find_substitution PARAMS ((tree));
00158
00159
00160
00161 static void write_mangled_name PARAMS ((tree));
00162 static void write_encoding PARAMS ((tree));
00163 static void write_name PARAMS ((tree, int));
00164 static void write_unscoped_name PARAMS ((tree));
00165 static void write_unscoped_template_name PARAMS ((tree));
00166 static void write_nested_name PARAMS ((tree));
00167 static void write_prefix PARAMS ((tree));
00168 static void write_template_prefix PARAMS ((tree));
00169 static void write_unqualified_name PARAMS ((tree));
00170 static void write_conversion_operator_name (tree);
00171 static void write_source_name PARAMS ((tree));
00172 static int hwint_to_ascii PARAMS ((unsigned HOST_WIDE_INT, unsigned int, char *, unsigned));
00173 static void write_number PARAMS ((unsigned HOST_WIDE_INT, int,
00174 unsigned int));
00175 static void write_integer_cst PARAMS ((tree));
00176 static void write_real_cst PARAMS ((tree));
00177 static void write_identifier PARAMS ((const char *));
00178 static void write_special_name_constructor PARAMS ((tree));
00179 static void write_special_name_destructor PARAMS ((tree));
00180 static void write_type PARAMS ((tree));
00181 static int write_CV_qualifiers_for_type PARAMS ((tree));
00182 static void write_builtin_type PARAMS ((tree));
00183 static void write_function_type PARAMS ((tree));
00184 static void write_bare_function_type PARAMS ((tree, int, tree));
00185 static void write_method_parms PARAMS ((tree, int, tree));
00186 static void write_class_enum_type PARAMS ((tree));
00187 static void write_template_args PARAMS ((tree));
00188 static void write_expression PARAMS ((tree));
00189 static void write_template_arg_literal PARAMS ((tree));
00190 static void write_template_arg PARAMS ((tree));
00191 static void write_template_template_arg PARAMS ((tree));
00192 static void write_array_type PARAMS ((tree));
00193 static void write_pointer_to_member_type PARAMS ((tree));
00194 static void write_template_param PARAMS ((tree));
00195 static void write_template_template_param PARAMS ((tree));
00196 static void write_substitution PARAMS ((int));
00197 static int discriminator_for_local_entity PARAMS ((tree));
00198 static int discriminator_for_string_literal PARAMS ((tree, tree));
00199 static void write_discriminator PARAMS ((int));
00200 static void write_local_name PARAMS ((tree, tree, tree));
00201 static void dump_substitution_candidates PARAMS ((void));
00202 static const char *mangle_decl_string PARAMS ((tree));
00203
00204
00205
00206 static inline void start_mangling (tree);
00207 static inline const char *finish_mangling (bool);
00208 static tree mangle_special_for_type PARAMS ((tree, const char *));
00209
00210
00211
00212 static void write_java_integer_type_codes PARAMS ((tree));
00213
00214
00215
00216 #define write_char(CHAR) \
00217 obstack_1grow (&G.name_obstack, (CHAR))
00218
00219
00220 #define write_chars(CHAR, LEN) \
00221 obstack_grow (&G.name_obstack, (CHAR), (LEN))
00222
00223
00224
00225 #define write_string(STRING) \
00226 obstack_grow (&G.name_obstack, (STRING), strlen (STRING))
00227
00228
00229
00230
00231
00232 #define NESTED_TEMPLATE_MATCH(NODE1, NODE2) \
00233 (TREE_CODE (NODE1) == TREE_LIST \
00234 && TREE_CODE (NODE2) == TREE_LIST \
00235 && ((TYPE_P (TREE_PURPOSE (NODE1)) \
00236 && same_type_p (TREE_PURPOSE (NODE1), TREE_PURPOSE (NODE2)))\
00237 || TREE_PURPOSE (NODE1) == TREE_PURPOSE (NODE2)) \
00238 && TREE_VALUE (NODE1) == TREE_VALUE (NODE2))
00239
00240
00241 #define write_unsigned_number(NUMBER) \
00242 write_number ((NUMBER), 1, 10)
00243
00244
00245
00246
00247
00248 static int
00249 decl_is_template_id (decl, template_info)
00250 tree decl;
00251 tree* template_info;
00252 {
00253 if (TREE_CODE (decl) == TYPE_DECL)
00254 {
00255
00256
00257 tree type = TREE_TYPE (decl);
00258
00259 if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_ID_P (type))
00260 {
00261 if (template_info != NULL)
00262
00263
00264 *template_info = TYPE_TEMPLATE_INFO (type);
00265 return 1;
00266 }
00267 }
00268 else
00269 {
00270
00271 if (DECL_LANG_SPECIFIC (decl) != NULL
00272 && DECL_USE_TEMPLATE (decl)
00273 && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl))
00274 && TREE_CODE (decl) != TEMPLATE_DECL)
00275 {
00276 if (template_info != NULL)
00277
00278
00279 *template_info = DECL_TEMPLATE_INFO (decl);
00280 return 1;
00281 }
00282 }
00283
00284
00285 return 0;
00286 }
00287
00288
00289
00290 static void
00291 dump_substitution_candidates ()
00292 {
00293 unsigned i;
00294
00295 fprintf (stderr, " ++ substitutions ");
00296 for (i = 0; i < VARRAY_ACTIVE_SIZE (G.substitutions); ++i)
00297 {
00298 tree el = VARRAY_TREE (G.substitutions, i);
00299 const char *name = "???";
00300
00301 if (i > 0)
00302 fprintf (stderr, " ");
00303 if (DECL_P (el))
00304 name = IDENTIFIER_POINTER (DECL_NAME (el));
00305 else if (TREE_CODE (el) == TREE_LIST)
00306 name = IDENTIFIER_POINTER (DECL_NAME (TREE_VALUE (el)));
00307 else if (TYPE_NAME (el))
00308 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (el)));
00309 fprintf (stderr, " S%d_ = ", i - 1);
00310 if (TYPE_P (el) &&
00311 (CP_TYPE_RESTRICT_P (el)
00312 || CP_TYPE_VOLATILE_P (el)
00313 || CP_TYPE_CONST_P (el)))
00314 fprintf (stderr, "CV-");
00315 fprintf (stderr, "%s (%s at %p)\n",
00316 name, tree_code_name[TREE_CODE (el)], (void *) el);
00317 }
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327 static inline tree
00328 canonicalize_for_substitution (node)
00329 tree node;
00330 {
00331
00332 if (TREE_CODE (node) == TYPE_DECL)
00333 node = TREE_TYPE (node);
00334 if (TYPE_P (node))
00335 node = canonical_type_variant (node);
00336
00337 return node;
00338 }
00339
00340
00341
00342
00343 static void
00344 add_substitution (node)
00345 tree node;
00346 {
00347 tree c;
00348
00349 if (DEBUG_MANGLE)
00350 fprintf (stderr, " ++ add_substitution (%s at %10p)\n",
00351 tree_code_name[TREE_CODE (node)], (void *) node);
00352
00353
00354 c = canonicalize_for_substitution (node);
00355 if (DEBUG_MANGLE && c != node)
00356 fprintf (stderr, " ++ using candidate (%s at %10p)\n",
00357 tree_code_name[TREE_CODE (node)], (void *) node);
00358 node = c;
00359
00360 #if ENABLE_CHECKING
00361
00362 {
00363 int i;
00364 for (i = VARRAY_ACTIVE_SIZE (G.substitutions); --i >= 0; )
00365 {
00366 tree candidate = VARRAY_TREE (G.substitutions, i);
00367 if ((DECL_P (node)
00368 && node == candidate)
00369 || (TYPE_P (node)
00370 && TYPE_P (candidate)
00371 && same_type_p (node, candidate)))
00372 abort ();
00373 }
00374 }
00375 #endif
00376
00377
00378 VARRAY_PUSH_TREE (G.substitutions, node);
00379
00380 if (DEBUG_MANGLE)
00381 dump_substitution_candidates ();
00382 }
00383
00384
00385
00386
00387
00388 static inline int
00389 is_std_substitution (node, index)
00390 tree node;
00391 substitution_identifier_index_t index;
00392 {
00393 tree type = NULL;
00394 tree decl = NULL;
00395
00396 if (DECL_P (node))
00397 {
00398 type = TREE_TYPE (node);
00399 decl = node;
00400 }
00401 else if (CLASS_TYPE_P (node))
00402 {
00403 type = node;
00404 decl = TYPE_NAME (node);
00405 }
00406 else
00407
00408 return 0;
00409
00410 return (DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl))
00411 && TYPE_LANG_SPECIFIC (type)
00412 && TYPE_TEMPLATE_INFO (type)
00413 && (DECL_NAME (TYPE_TI_TEMPLATE (type))
00414 == subst_identifiers[index]));
00415 }
00416
00417
00418
00419
00420
00421
00422 static inline int
00423 is_std_substitution_char (node, index)
00424 tree node;
00425 substitution_identifier_index_t index;
00426 {
00427 tree args;
00428
00429 if (!is_std_substitution (node, index))
00430 return 0;
00431
00432 if (DECL_P (node))
00433 args = DECL_TI_ARGS (node);
00434 else if (CLASS_TYPE_P (node))
00435 args = CLASSTYPE_TI_ARGS (node);
00436 else
00437
00438 return 0;
00439
00440 return
00441 TREE_VEC_LENGTH (args) == 1
00442 && TREE_VEC_ELT (args, 0) == char_type_node;
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 static int
00480 find_substitution (node)
00481 tree node;
00482 {
00483 int i;
00484 int size = VARRAY_ACTIVE_SIZE (G.substitutions);
00485 tree decl;
00486 tree type;
00487
00488 if (DEBUG_MANGLE)
00489 fprintf (stderr, " ++ find_substitution (%s at %p)\n",
00490 tree_code_name[TREE_CODE (node)], (void *) node);
00491
00492
00493
00494 node = canonicalize_for_substitution (node);
00495
00496
00497
00498 decl = TYPE_P (node) ? TYPE_NAME (node) : node;
00499 type = TYPE_P (node) ? node : TREE_TYPE (node);
00500
00501
00502 if (decl
00503 && is_std_substitution (decl, SUBID_ALLOCATOR)
00504 && !CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)))
00505 {
00506 write_string ("Sa");
00507 return 1;
00508 }
00509
00510
00511 if (decl && is_std_substitution (decl, SUBID_BASIC_STRING))
00512 {
00513 if (TYPE_P (node))
00514 {
00515
00516
00517
00518
00519
00520 if (cp_type_quals (type) == TYPE_UNQUALIFIED
00521 && CLASSTYPE_USE_TEMPLATE (type))
00522 {
00523 tree args = CLASSTYPE_TI_ARGS (type);
00524 if (TREE_VEC_LENGTH (args) == 3
00525 && same_type_p (TREE_VEC_ELT (args, 0), char_type_node)
00526 && is_std_substitution_char (TREE_VEC_ELT (args, 1),
00527 SUBID_CHAR_TRAITS)
00528 && is_std_substitution_char (TREE_VEC_ELT (args, 2),
00529 SUBID_ALLOCATOR))
00530 {
00531 write_string ("Ss");
00532 return 1;
00533 }
00534 }
00535 }
00536 else
00537
00538 {
00539 write_string ("Sb");
00540 return 1;
00541 }
00542 }
00543
00544
00545 if (TYPE_P (node)
00546 && cp_type_quals (type) == TYPE_UNQUALIFIED
00547 && CLASS_TYPE_P (type)
00548 && CLASSTYPE_USE_TEMPLATE (type)
00549 && CLASSTYPE_TEMPLATE_INFO (type) != NULL)
00550 {
00551
00552
00553 tree args = CLASSTYPE_TI_ARGS (type);
00554 if (TREE_VEC_LENGTH (args) == 2
00555 && same_type_p (TREE_VEC_ELT (args, 0), char_type_node)
00556 && is_std_substitution_char (TREE_VEC_ELT (args, 1),
00557 SUBID_CHAR_TRAITS))
00558 {
00559
00560 tree name = DECL_NAME (CLASSTYPE_TI_TEMPLATE (type));
00561 if (name == subst_identifiers[SUBID_BASIC_ISTREAM])
00562 {
00563 write_string ("Si");
00564 return 1;
00565 }
00566
00567 else if (name == subst_identifiers[SUBID_BASIC_OSTREAM])
00568 {
00569 write_string ("So");
00570 return 1;
00571 }
00572
00573 else if (name == subst_identifiers[SUBID_BASIC_IOSTREAM])
00574 {
00575 write_string ("Sd");
00576 return 1;
00577 }
00578 }
00579 }
00580
00581
00582 if (decl && DECL_NAMESPACE_STD_P (decl))
00583 {
00584 write_string ("St");
00585 return 1;
00586 }
00587
00588
00589
00590 for (i = 0; i < size; ++i)
00591 {
00592 tree candidate = VARRAY_TREE (G.substitutions, i);
00593
00594
00595 if (decl == candidate
00596 || (TYPE_P (candidate) && type && TYPE_P (type)
00597 && same_type_p (type, candidate))
00598 || NESTED_TEMPLATE_MATCH (node, candidate))
00599 {
00600 write_substitution (i);
00601 return 1;
00602 }
00603 }
00604
00605
00606 return 0;
00607 }
00608
00609
00610
00611
00612 static inline void
00613 write_mangled_name (decl)
00614 tree decl;
00615 {
00616 MANGLE_TRACE_TREE ("mangled-name", decl);
00617
00618 if (DECL_LANG_SPECIFIC (decl)
00619 && DECL_EXTERN_C_FUNCTION_P (decl)
00620 && ! DECL_OVERLOADED_OPERATOR_P (decl))
00621
00622
00623
00624
00625
00626 write_source_name (DECL_NAME (decl));
00627 else
00628
00629 {
00630 write_string ("_Z");
00631 write_encoding (decl);
00632 }
00633 }
00634
00635
00636
00637
00638 static void
00639 write_encoding (decl)
00640 tree decl;
00641 {
00642 MANGLE_TRACE_TREE ("encoding", decl);
00643
00644 if (DECL_LANG_SPECIFIC (decl) && DECL_EXTERN_C_FUNCTION_P (decl))
00645 {
00646
00647
00648 if (DECL_OVERLOADED_OPERATOR_P (decl))
00649 write_name (decl, 0);
00650 else
00651 write_source_name (DECL_NAME (decl));
00652 return;
00653 }
00654
00655 write_name (decl, 0);
00656 if (TREE_CODE (decl) == FUNCTION_DECL)
00657 {
00658 tree fn_type;
00659
00660 if (decl_is_template_id (decl, NULL))
00661 fn_type = get_mostly_instantiated_function_type (decl);
00662 else
00663 fn_type = TREE_TYPE (decl);
00664
00665 write_bare_function_type (fn_type,
00666 (!DECL_CONSTRUCTOR_P (decl)
00667 && !DECL_DESTRUCTOR_P (decl)
00668 && !DECL_CONV_FN_P (decl)
00669 && decl_is_template_id (decl, NULL)),
00670 decl);
00671 }
00672 }
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 static void
00686 write_name (decl, ignore_local_scope)
00687 tree decl;
00688 int ignore_local_scope;
00689 {
00690 tree context;
00691
00692 MANGLE_TRACE_TREE ("name", decl);
00693
00694 if (TREE_CODE (decl) == TYPE_DECL)
00695 {
00696
00697
00698 decl = TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl)));
00699 context = TYPE_CONTEXT (TYPE_MAIN_VARIANT (TREE_TYPE (decl)));
00700 }
00701 else
00702 context = (DECL_CONTEXT (decl) == NULL) ? NULL : CP_DECL_CONTEXT (decl);
00703
00704
00705
00706
00707
00708
00709 if (context == NULL
00710 || context == global_namespace
00711 || DECL_NAMESPACE_STD_P (context)
00712 || (ignore_local_scope && TREE_CODE (context) == FUNCTION_DECL))
00713 {
00714 tree template_info;
00715
00716 if (decl_is_template_id (decl, &template_info))
00717 {
00718
00719 write_unscoped_template_name (TI_TEMPLATE (template_info));
00720 write_template_args (TI_ARGS (template_info));
00721 }
00722 else
00723
00724 write_unscoped_name (decl);
00725 }
00726 else
00727 {
00728
00729
00730
00731 if (!ignore_local_scope)
00732 {
00733
00734
00735
00736
00737
00738
00739 tree local_entity = decl;
00740 while (context != NULL && context != global_namespace)
00741 {
00742
00743 if (context != NULL && TYPE_P (context))
00744 context = TYPE_NAME (context);
00745
00746 if (TREE_CODE (context) == FUNCTION_DECL)
00747 {
00748
00749
00750 write_local_name (context, local_entity, decl);
00751 return;
00752 }
00753
00754 local_entity = context;
00755 context = CP_DECL_CONTEXT (context);
00756 }
00757
00758
00759 }
00760
00761
00762 write_nested_name (decl);
00763 }
00764 }
00765
00766
00767
00768
00769 static void
00770 write_unscoped_name (decl)
00771 tree decl;
00772 {
00773 tree context = CP_DECL_CONTEXT (decl);
00774
00775 MANGLE_TRACE_TREE ("unscoped-name", decl);
00776
00777
00778 if (DECL_NAMESPACE_STD_P (context))
00779 {
00780 write_string ("St");
00781 write_unqualified_name (decl);
00782 }
00783
00784
00785 else if (context == global_namespace
00786 || context == NULL
00787 || TREE_CODE (context) == FUNCTION_DECL)
00788 write_unqualified_name (decl);
00789 else
00790 abort ();
00791 }
00792
00793
00794
00795
00796 static void
00797 write_unscoped_template_name (decl)
00798 tree decl;
00799 {
00800 MANGLE_TRACE_TREE ("unscoped-template-name", decl);
00801
00802 if (find_substitution (decl))
00803 return;
00804 write_unscoped_name (decl);
00805 add_substitution (decl);
00806 }
00807
00808
00809
00810
00811
00812
00813
00814
00815 static void
00816 write_nested_name (decl)
00817 tree decl;
00818 {
00819 tree template_info;
00820
00821 MANGLE_TRACE_TREE ("nested-name", decl);
00822
00823 write_char ('N');
00824
00825
00826 if (TREE_CODE (decl) == FUNCTION_DECL
00827 && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
00828 {
00829 if (DECL_VOLATILE_MEMFUNC_P (decl))
00830 write_char ('V');
00831 if (DECL_CONST_MEMFUNC_P (decl))
00832 write_char ('K');
00833 }
00834
00835
00836 if (decl_is_template_id (decl, &template_info))
00837 {
00838
00839 write_template_prefix (decl);
00840 write_template_args (TI_ARGS (template_info));
00841 }
00842 else
00843 {
00844
00845 write_prefix (DECL_CONTEXT (decl));
00846 write_unqualified_name (decl);
00847 }
00848 write_char ('E');
00849 }
00850
00851
00852
00853
00854
00855
00856
00857 static void
00858 write_prefix (node)
00859 tree node;
00860 {
00861 tree decl;
00862
00863 tree template_info = NULL;
00864
00865 MANGLE_TRACE_TREE ("prefix", node);
00866
00867 if (node == NULL
00868 || node == global_namespace)
00869 return;
00870
00871 if (find_substitution (node))
00872 return;
00873
00874 if (DECL_P (node))
00875 {
00876
00877
00878
00879
00880
00881 if (TREE_CODE (node) == FUNCTION_DECL)
00882 return;
00883
00884 decl = node;
00885 decl_is_template_id (decl, &template_info);
00886 }
00887 else
00888 {
00889
00890 decl = TYPE_NAME (node);
00891 if (CLASSTYPE_TEMPLATE_ID_P (node))
00892 template_info = TYPE_TEMPLATE_INFO (node);
00893 }
00894
00895
00896 if (TREE_CODE (node) == TEMPLATE_TYPE_PARM
00897 && !abi_version_at_least (2))
00898 G.need_abi_warning = true;
00899
00900 if (TREE_CODE (node) == TEMPLATE_TYPE_PARM
00901 && abi_version_at_least (2))
00902 write_template_param (node);
00903 else if (template_info != NULL)
00904
00905 {
00906 write_template_prefix (decl);
00907 write_template_args (TI_ARGS (template_info));
00908 }
00909 else
00910
00911 {
00912 write_prefix (CP_DECL_CONTEXT (decl));
00913 write_unqualified_name (decl);
00914 }
00915
00916 add_substitution (node);
00917 }
00918
00919
00920
00921
00922
00923 static void
00924 write_template_prefix (node)
00925 tree node;
00926 {
00927 tree decl = DECL_P (node) ? node : TYPE_NAME (node);
00928 tree type = DECL_P (node) ? TREE_TYPE (node) : node;
00929 tree context = CP_DECL_CONTEXT (decl);
00930 tree template_info;
00931 tree template;
00932 tree substitution;
00933
00934 MANGLE_TRACE_TREE ("template-prefix", node);
00935
00936
00937 if (decl_is_template_id (decl, &template_info))
00938 template = TI_TEMPLATE (template_info);
00939 else if (CLASSTYPE_TEMPLATE_ID_P (type))
00940 template = TYPE_TI_TEMPLATE (type);
00941 else
00942
00943 abort ();
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967 if (TYPE_P (context))
00968 substitution = build_tree_list (context, template);
00969 else
00970 substitution = template;
00971
00972 if (find_substitution (substitution))
00973 return;
00974
00975
00976 if (TREE_CODE (TREE_TYPE (template)) == TEMPLATE_TEMPLATE_PARM
00977 && !abi_version_at_least (2))
00978 G.need_abi_warning = true;
00979
00980 if (TREE_CODE (TREE_TYPE (template)) == TEMPLATE_TEMPLATE_PARM
00981 && abi_version_at_least (2))
00982 write_template_param (TREE_TYPE (template));
00983 else
00984 {
00985 write_prefix (context);
00986 write_unqualified_name (decl);
00987 }
00988
00989 add_substitution (substitution);
00990 }
00991
00992
00993
00994
00995
00996
00997
00998
00999 static void
01000 write_unqualified_name (decl)
01001 tree decl;
01002 {
01003 MANGLE_TRACE_TREE ("unqualified-name", decl);
01004
01005 if (DECL_LANG_SPECIFIC (decl) != NULL && DECL_CONSTRUCTOR_P (decl))
01006 write_special_name_constructor (decl);
01007 else if (DECL_LANG_SPECIFIC (decl) != NULL && DECL_DESTRUCTOR_P (decl))
01008 write_special_name_destructor (decl);
01009 else if (DECL_CONV_FN_P (decl))
01010 {
01011
01012
01013 tree type;
01014 if (decl_is_template_id (decl, NULL))
01015 {
01016 tree fn_type = get_mostly_instantiated_function_type (decl);
01017 type = TREE_TYPE (fn_type);
01018 }
01019 else
01020 type = DECL_CONV_FN_TYPE (decl);
01021 write_conversion_operator_name (type);
01022 }
01023 else if (DECL_OVERLOADED_OPERATOR_P (decl))
01024 {
01025 operator_name_info_t *oni;
01026 if (DECL_ASSIGNMENT_OPERATOR_P (decl))
01027 oni = assignment_operator_name_info;
01028 else
01029 oni = operator_name_info;
01030
01031 write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name);
01032 }
01033 else
01034 write_source_name (DECL_NAME (decl));
01035 }
01036
01037
01038
01039 static void
01040 write_conversion_operator_name (tree type)
01041 {
01042 write_string ("cv");
01043 write_type (type);
01044 }
01045
01046
01047
01048
01049
01050 static void
01051 write_source_name (identifier)
01052 tree identifier;
01053 {
01054 MANGLE_TRACE_TREE ("source-name", identifier);
01055
01056
01057
01058 if (IDENTIFIER_TEMPLATE (identifier))
01059 identifier = IDENTIFIER_TEMPLATE (identifier);
01060
01061 write_unsigned_number (IDENTIFIER_LENGTH (identifier));
01062 write_identifier (IDENTIFIER_POINTER (identifier));
01063 }
01064
01065
01066
01067
01068
01069
01070
01071 static int
01072 hwint_to_ascii (number, base, buffer, min_digits)
01073 unsigned HOST_WIDE_INT number;
01074 unsigned int base;
01075 char *buffer;
01076 unsigned min_digits;
01077 {
01078 static const char base_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
01079 unsigned digits = 0;
01080
01081 while (number)
01082 {
01083 unsigned HOST_WIDE_INT d = number / base;
01084
01085 *--buffer = base_digits[number - d * base];
01086 digits++;
01087 number = d;
01088 }
01089 while (digits < min_digits)
01090 {
01091 *--buffer = base_digits[0];
01092 digits++;
01093 }
01094 return digits;
01095 }
01096
01097
01098
01099
01100
01101 static void
01102 write_number (number, unsigned_p, base)
01103 unsigned HOST_WIDE_INT number;
01104 int unsigned_p;
01105 unsigned int base;
01106 {
01107 char buffer[sizeof (HOST_WIDE_INT) * 8];
01108 unsigned count = 0;
01109
01110 if (!unsigned_p && (HOST_WIDE_INT) number < 0)
01111 {
01112 write_char ('n');
01113 number = -((HOST_WIDE_INT) number);
01114 }
01115 count = hwint_to_ascii (number, base, buffer + sizeof (buffer), 1);
01116 write_chars (buffer + sizeof (buffer) - count, count);
01117 }
01118
01119
01120
01121
01122
01123 static inline void
01124 write_integer_cst (cst)
01125 tree cst;
01126 {
01127 int sign = tree_int_cst_sgn (cst);
01128
01129 if (TREE_INT_CST_HIGH (cst) + (sign < 0))
01130 {
01131
01132
01133 char buffer[sizeof (HOST_WIDE_INT) * 8 * 2];
01134 unsigned HOST_WIDE_INT chunk;
01135 unsigned chunk_digits;
01136 char *ptr = buffer + sizeof (buffer);
01137 unsigned count = 0;
01138 tree n, base, type;
01139 int done;
01140
01141
01142
01143 chunk = 1000000000;
01144 chunk_digits = 9;
01145
01146 if (sizeof (HOST_WIDE_INT) >= 8)
01147 {
01148
01149 chunk_digits = 18;
01150 chunk *= chunk;
01151 }
01152
01153 type = c_common_signed_or_unsigned_type (1, TREE_TYPE (cst));
01154 base = build_int_2 (chunk, 0);
01155 n = build_int_2 (TREE_INT_CST_LOW (cst), TREE_INT_CST_HIGH (cst));
01156 TREE_TYPE (n) = TREE_TYPE (base) = type;
01157
01158 if (sign < 0)
01159 {
01160 write_char ('n');
01161 n = fold (build1 (NEGATE_EXPR, type, n));
01162 }
01163 do
01164 {
01165 tree d = fold (build (FLOOR_DIV_EXPR, type, n, base));
01166 tree tmp = fold (build (MULT_EXPR, type, d, base));
01167 unsigned c;
01168
01169 done = integer_zerop (d);
01170 tmp = fold (build (MINUS_EXPR, type, n, tmp));
01171 c = hwint_to_ascii (TREE_INT_CST_LOW (tmp), 10, ptr,
01172 done ? 1 : chunk_digits);
01173 ptr -= c;
01174 count += c;
01175 n = d;
01176 }
01177 while (!done);
01178 write_chars (ptr, count);
01179 }
01180 else
01181 {
01182
01183 unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (cst);
01184
01185 if (sign < 0)
01186 {
01187 write_char ('n');
01188 low = -low;
01189 }
01190 write_unsigned_number (low);
01191 }
01192 }
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214 static void
01215 write_real_cst (value)
01216 tree value;
01217 {
01218 if (abi_version_at_least (2))
01219 {
01220 long target_real[4];
01221 char buffer[9];
01222 int i, limit, dir;
01223
01224 tree type = TREE_TYPE (value);
01225 int words = GET_MODE_BITSIZE (TYPE_MODE (type)) / 32;
01226
01227 real_to_target (target_real, &TREE_REAL_CST (value),
01228 TYPE_MODE (type));
01229
01230
01231
01232
01233
01234 if (FLOAT_WORDS_BIG_ENDIAN)
01235 i = 0, limit = words, dir = 1;
01236 else
01237 i = words - 1, limit = -1, dir = -1;
01238
01239 for (; i != limit; i += dir)
01240 {
01241 sprintf (buffer, "%08lx", target_real[i]);
01242 write_chars (buffer, 8);
01243 }
01244 }
01245 else
01246 {
01247
01248
01249
01250
01251 size_t i;
01252 for (i = 0; i < sizeof (TREE_REAL_CST (value)); ++i)
01253 write_number (((unsigned char *) &TREE_REAL_CST (value))[i],
01254 1,
01255 16);
01256 G.need_abi_warning = 1;
01257 }
01258 }
01259
01260
01261
01262
01263
01264 static void
01265 write_identifier (identifier)
01266 const char *identifier;
01267 {
01268 MANGLE_TRACE ("identifier", identifier);
01269 write_string (identifier);
01270 }
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285 static void
01286 write_special_name_constructor (ctor)
01287 tree ctor;
01288 {
01289 if (DECL_COMPLETE_CONSTRUCTOR_P (ctor)
01290
01291
01292
01293 || DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (ctor))
01294 write_string ("C1");
01295 else if (DECL_BASE_CONSTRUCTOR_P (ctor))
01296 write_string ("C2");
01297 else
01298 abort ();
01299 }
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312 static void
01313 write_special_name_destructor (dtor)
01314 tree dtor;
01315 {
01316 if (DECL_DELETING_DESTRUCTOR_P (dtor))
01317 write_string ("D0");
01318 else if (DECL_COMPLETE_DESTRUCTOR_P (dtor)
01319
01320
01321
01322 || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (dtor))
01323 write_string ("D1");
01324 else if (DECL_BASE_DESTRUCTOR_P (dtor))
01325 write_string ("D2");
01326 else
01327 abort ();
01328 }
01329
01330
01331
01332
01333
01334 static int
01335 discriminator_for_local_entity (entity)
01336 tree entity;
01337 {
01338 tree *type;
01339 int discriminator;
01340
01341
01342 discriminator = 0;
01343
01344 if (DECL_DISCRIMINATOR_P (entity) && DECL_LANG_SPECIFIC (entity))
01345 discriminator = DECL_DISCRIMINATOR (entity);
01346 else if (TREE_CODE (entity) == TYPE_DECL)
01347 {
01348
01349 entity = TREE_TYPE (entity);
01350 for (type = &VARRAY_TREE (local_classes, 0); *type != entity; ++type)
01351 if (TYPE_IDENTIFIER (*type) == TYPE_IDENTIFIER (entity)
01352 && TYPE_CONTEXT (*type) == TYPE_CONTEXT (entity))
01353 ++discriminator;
01354 }
01355
01356 return discriminator;
01357 }
01358
01359
01360
01361
01362
01363 static int
01364 discriminator_for_string_literal (function, string)
01365 tree function ATTRIBUTE_UNUSED;
01366 tree string ATTRIBUTE_UNUSED;
01367 {
01368
01369 return 0;
01370 }
01371
01372
01373
01374
01375
01376
01377
01378 static void
01379 write_discriminator (discriminator)
01380 int discriminator;
01381 {
01382
01383 if (discriminator > 0)
01384 {
01385 write_char ('_');
01386 write_unsigned_number (discriminator - 1);
01387 }
01388 }
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399 static void
01400 write_local_name (function, local_entity, entity)
01401 tree function;
01402 tree local_entity;
01403 tree entity;
01404 {
01405 MANGLE_TRACE_TREE ("local-name", entity);
01406
01407 write_char ('Z');
01408 write_encoding (function);
01409 write_char ('E');
01410 if (TREE_CODE (entity) == STRING_CST)
01411 {
01412 write_char ('s');
01413 write_discriminator (discriminator_for_string_literal (function,
01414 entity));
01415 }
01416 else
01417 {
01418
01419
01420
01421 write_name (entity, 1);
01422 write_discriminator (discriminator_for_local_entity (local_entity));
01423 }
01424 }
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444 static void
01445 write_type (type)
01446 tree type;
01447 {
01448
01449
01450 int is_builtin_type = 0;
01451
01452 MANGLE_TRACE_TREE ("type", type);
01453
01454 if (type == error_mark_node)
01455 return;
01456
01457 if (find_substitution (type))
01458 return;
01459
01460 if (write_CV_qualifiers_for_type (type) > 0)
01461
01462
01463
01464
01465 write_type (TYPE_MAIN_VARIANT (type));
01466 else if (TREE_CODE (type) == ARRAY_TYPE)
01467
01468
01469
01470 write_array_type (type);
01471 else
01472 {
01473
01474 type = TYPE_MAIN_VARIANT (type);
01475
01476 switch (TREE_CODE (type))
01477 {
01478 case VOID_TYPE:
01479 case BOOLEAN_TYPE:
01480 case INTEGER_TYPE:
01481 case REAL_TYPE:
01482
01483
01484
01485 write_builtin_type (TYPE_MAIN_VARIANT (type));
01486 ++is_builtin_type;
01487 break;
01488
01489 case COMPLEX_TYPE:
01490 write_char ('C');
01491 write_type (TREE_TYPE (type));
01492 break;
01493
01494 case FUNCTION_TYPE:
01495 case METHOD_TYPE:
01496 write_function_type (type);
01497 break;
01498
01499 case UNION_TYPE:
01500 case RECORD_TYPE:
01501 case ENUMERAL_TYPE:
01502
01503
01504 if (TYPE_PTRMEMFUNC_P (type))
01505 write_pointer_to_member_type (type);
01506 else
01507 write_class_enum_type (type);
01508 break;
01509
01510 case TYPENAME_TYPE:
01511 case UNBOUND_CLASS_TEMPLATE:
01512
01513
01514 write_nested_name (TYPE_STUB_DECL (type));
01515 break;
01516
01517 case POINTER_TYPE:
01518
01519
01520 if (TYPE_PTRMEM_P (type))
01521 write_pointer_to_member_type (type);
01522 else
01523 {
01524 write_char ('P');
01525 write_type (TREE_TYPE (type));
01526 }
01527 break;
01528
01529 case REFERENCE_TYPE:
01530 write_char ('R');
01531 write_type (TREE_TYPE (type));
01532 break;
01533
01534 case TEMPLATE_TYPE_PARM:
01535 case TEMPLATE_PARM_INDEX:
01536 write_template_param (type);
01537 break;
01538
01539 case TEMPLATE_TEMPLATE_PARM:
01540 write_template_template_param (type);
01541 break;
01542
01543 case BOUND_TEMPLATE_TEMPLATE_PARM:
01544 write_template_template_param (type);
01545 write_template_args
01546 (TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type)));
01547 break;
01548
01549 case OFFSET_TYPE:
01550 write_pointer_to_member_type (build_pointer_type (type));
01551 break;
01552
01553 case VECTOR_TYPE:
01554 write_string ("U8__vector");
01555 write_type (TREE_TYPE (type));
01556 break;
01557
01558 default:
01559 abort ();
01560 }
01561 }
01562
01563
01564 if (!is_builtin_type)
01565 add_substitution (type);
01566 }
01567
01568
01569
01570
01571
01572
01573 static int
01574 write_CV_qualifiers_for_type (type)
01575 tree type;
01576 {
01577 int num_qualifiers = 0;
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589 if (TYPE_QUALS (type) & TYPE_QUAL_RESTRICT)
01590 {
01591 write_char ('r');
01592 ++num_qualifiers;
01593 }
01594 if (TYPE_QUALS (type) & TYPE_QUAL_VOLATILE)
01595 {
01596 write_char ('V');
01597 ++num_qualifiers;
01598 }
01599 if (TYPE_QUALS (type) & TYPE_QUAL_CONST)
01600 {
01601 write_char ('K');
01602 ++num_qualifiers;
01603 }
01604
01605 return num_qualifiers;
01606 }
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632 static void
01633 write_builtin_type (type)
01634 tree type;
01635 {
01636 switch (TREE_CODE (type))
01637 {
01638 case VOID_TYPE:
01639 write_char ('v');
01640 break;
01641
01642 case BOOLEAN_TYPE:
01643 write_char ('b');
01644 break;
01645
01646 case INTEGER_TYPE:
01647
01648 if (TYPE_IS_SIZETYPE (type))
01649 type = TYPE_DOMAIN (type);
01650
01651
01652
01653 if (type == wchar_type_node)
01654 write_char ('w');
01655 else if (TYPE_FOR_JAVA (type))
01656 write_java_integer_type_codes (type);
01657 else
01658 {
01659 size_t itk;
01660
01661
01662 iagain:
01663 for (itk = 0; itk < itk_none; ++itk)
01664 if (type == integer_types[itk])
01665 {
01666
01667 write_char (integer_type_codes[itk]);
01668 break;
01669 }
01670
01671 if (itk == itk_none)
01672 {
01673 tree t = c_common_type_for_mode (TYPE_MODE (type),
01674 TREE_UNSIGNED (type));
01675 if (type == t)
01676 {
01677 if (TYPE_PRECISION (type) == 128)
01678 write_char (TREE_UNSIGNED (type) ? 'o' : 'n');
01679 else
01680
01681 abort ();
01682 }
01683 else
01684 {
01685 type = t;
01686 goto iagain;
01687 }
01688 }
01689 }
01690 break;
01691
01692 case REAL_TYPE:
01693 if (type == float_type_node
01694 || type == java_float_type_node)
01695 write_char ('f');
01696 else if (type == double_type_node
01697 || type == java_double_type_node)
01698 write_char ('d');
01699 else if (type == long_double_type_node)
01700 write_char ('e');
01701 else
01702 abort ();
01703 break;
01704
01705 default:
01706 abort ();
01707 }
01708 }
01709
01710
01711
01712
01713
01714
01715
01716 static void
01717 write_function_type (type)
01718 tree type;
01719 {
01720 MANGLE_TRACE_TREE ("function-type", type);
01721
01722
01723
01724
01725 if (TREE_CODE (type) == METHOD_TYPE)
01726 {
01727
01728
01729 tree this_type = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type)));
01730 write_CV_qualifiers_for_type (this_type);
01731 }
01732
01733 write_char ('F');
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746 write_bare_function_type (type, 1,
01747 NULL);
01748 write_char ('E');
01749 }
01750
01751
01752
01753
01754
01755
01756
01757
01758 static void
01759 write_bare_function_type (type, include_return_type_p, decl)
01760 tree type;
01761 int include_return_type_p;
01762 tree decl;
01763 {
01764 MANGLE_TRACE_TREE ("bare-function-type", type);
01765
01766
01767 if (include_return_type_p)
01768 write_type (TREE_TYPE (type));
01769
01770
01771 write_method_parms (TYPE_ARG_TYPES (type),
01772 TREE_CODE (type) == METHOD_TYPE,
01773 decl);
01774 }
01775
01776
01777
01778
01779
01780
01781
01782 static void
01783 write_method_parms (parm_types, method_p, decl)
01784 tree decl;
01785 tree parm_types;
01786 int method_p;
01787 {
01788 tree first_parm_type;
01789 tree parm_decl = decl ? DECL_ARGUMENTS (decl) : NULL_TREE;
01790
01791
01792
01793 int varargs_p = 1;
01794
01795
01796
01797
01798
01799
01800
01801
01802 if (method_p)
01803 {
01804 parm_types = TREE_CHAIN (parm_types);
01805 parm_decl = parm_decl ? TREE_CHAIN (parm_decl) : NULL_TREE;
01806
01807 while (parm_decl && DECL_ARTIFICIAL (parm_decl))
01808 {
01809 parm_types = TREE_CHAIN (parm_types);
01810 parm_decl = TREE_CHAIN (parm_decl);
01811 }
01812 }
01813
01814 for (first_parm_type = parm_types;
01815 parm_types;
01816 parm_types = TREE_CHAIN (parm_types))
01817 {
01818 tree parm = TREE_VALUE (parm_types);
01819 if (parm == void_type_node)
01820 {
01821
01822
01823
01824 if (parm_types == first_parm_type)
01825 write_type (parm);
01826
01827
01828 varargs_p = 0;
01829
01830 my_friendly_assert (TREE_CHAIN (parm_types) == NULL, 20000523);
01831 }
01832 else
01833 write_type (parm);
01834 }
01835
01836 if (varargs_p)
01837
01838 write_char ('z');
01839 }
01840
01841
01842
01843 static void
01844 write_class_enum_type (type)
01845 tree type;
01846 {
01847 write_name (TYPE_NAME (type), 0);
01848 }
01849
01850
01851
01852
01853
01854
01855 static void
01856 write_template_args (args)
01857 tree args;
01858 {
01859 MANGLE_TRACE_TREE ("template-args", args);
01860
01861 write_char ('I');
01862
01863 if (TREE_CODE (args) == TREE_VEC)
01864 {
01865 int i;
01866 int length = TREE_VEC_LENGTH (args);
01867 my_friendly_assert (length > 0, 20000422);
01868
01869 if (TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
01870 {
01871
01872
01873 args = TREE_VEC_ELT (args, length - 1);
01874 length = TREE_VEC_LENGTH (args);
01875 }
01876 for (i = 0; i < length; ++i)
01877 write_template_arg (TREE_VEC_ELT (args, i));
01878 }
01879 else
01880 {
01881 my_friendly_assert (TREE_CODE (args) == TREE_LIST, 20021014);
01882
01883 while (args)
01884 {
01885 write_template_arg (TREE_VALUE (args));
01886 args = TREE_CHAIN (args);
01887 }
01888 }
01889
01890 write_char ('E');
01891 }
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903 static void
01904 write_expression (expr)
01905 tree expr;
01906 {
01907 enum tree_code code;
01908
01909 code = TREE_CODE (expr);
01910
01911
01912
01913 if (code == PTRMEM_CST)
01914 {
01915 expr = build_nt (ADDR_EXPR,
01916 build_nt (SCOPE_REF,
01917 PTRMEM_CST_CLASS (expr),
01918 PTRMEM_CST_MEMBER (expr)));
01919 code = TREE_CODE (expr);
01920 }
01921
01922
01923
01924
01925 while (TREE_CODE (expr) == NOP_EXPR
01926 || TREE_CODE (expr) == NON_LVALUE_EXPR)
01927 {
01928 expr = TREE_OPERAND (expr, 0);
01929 code = TREE_CODE (expr);
01930 }
01931
01932
01933 if (code == TEMPLATE_TYPE_PARM
01934 || code == TEMPLATE_TEMPLATE_PARM
01935 || code == BOUND_TEMPLATE_TEMPLATE_PARM
01936 || code == TEMPLATE_PARM_INDEX)
01937 write_template_param (expr);
01938
01939 else if (TREE_CODE_CLASS (code) == 'c'
01940 || (abi_version_at_least (2) && code == CONST_DECL))
01941 write_template_arg_literal (expr);
01942 else if (DECL_P (expr))
01943 {
01944
01945
01946 if (code == CONST_DECL)
01947 G.need_abi_warning = 1;
01948 write_char ('L');
01949 write_mangled_name (expr);
01950 write_char ('E');
01951 }
01952 else if (TREE_CODE (expr) == SIZEOF_EXPR
01953 && TYPE_P (TREE_OPERAND (expr, 0)))
01954 {
01955 write_string ("st");
01956 write_type (TREE_OPERAND (expr, 0));
01957 }
01958 else if (abi_version_at_least (2) && TREE_CODE (expr) == SCOPE_REF)
01959 {
01960 tree scope = TREE_OPERAND (expr, 0);
01961 tree member = TREE_OPERAND (expr, 1);
01962
01963
01964
01965
01966
01967
01968 if (DECL_P (member))
01969 write_expression (member);
01970 else
01971 {
01972 tree template_args;
01973
01974 write_string ("sr");
01975 write_type (scope);
01976
01977
01978 if (TREE_CODE (member) == TEMPLATE_ID_EXPR)
01979 {
01980 template_args = TREE_OPERAND (member, 1);
01981 member = TREE_OPERAND (member, 0);
01982 if (TREE_CODE (member) == LOOKUP_EXPR)
01983 member = TREE_OPERAND (member, 0);
01984 }
01985 else
01986 template_args = NULL_TREE;
01987
01988 if (IDENTIFIER_TYPENAME_P (member))
01989 write_conversion_operator_name (TREE_TYPE (member));
01990 else if (IDENTIFIER_OPNAME_P (member))
01991 {
01992 int i;
01993 const char *mangled_name = NULL;
01994
01995
01996
01997
01998 for (i = 0; i < LAST_CPLUS_TREE_CODE; ++i)
01999 if (operator_name_info[i].identifier == member)
02000 {
02001
02002
02003 if (operator_name_info[i].arity == 2)
02004 {
02005 mangled_name = operator_name_info[i].mangled_name;
02006 break;
02007 }
02008 else if (!mangled_name)
02009 mangled_name = operator_name_info[i].mangled_name;
02010 }
02011 else if (assignment_operator_name_info[i].identifier
02012 == member)
02013 {
02014 mangled_name
02015 = assignment_operator_name_info[i].mangled_name;
02016 break;
02017 }
02018 write_string (mangled_name);
02019 }
02020 else
02021 write_source_name (member);
02022
02023 if (template_args)
02024 write_template_args (template_args);
02025 }
02026 }
02027 else
02028 {
02029 int i;
02030
02031
02032
02033
02034
02035 if (TREE_CODE (expr) == ADDR_EXPR
02036 && TREE_TYPE (expr)
02037 && TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE)
02038 {
02039 expr = TREE_OPERAND (expr, 0);
02040 if (DECL_P (expr))
02041 {
02042 write_expression (expr);
02043 return;
02044 }
02045
02046 code = TREE_CODE (expr);
02047 }
02048
02049
02050 write_string (operator_name_info[(int) code].mangled_name);
02051
02052 switch (code)
02053 {
02054 case CALL_EXPR:
02055 sorry ("call_expr cannot be mangled due to a defect in the C++ ABI");
02056 break;
02057
02058 case CAST_EXPR:
02059 write_type (TREE_TYPE (expr));
02060 write_expression (TREE_VALUE (TREE_OPERAND (expr, 0)));
02061 break;
02062
02063 case STATIC_CAST_EXPR:
02064 case CONST_CAST_EXPR:
02065 write_type (TREE_TYPE (expr));
02066 write_expression (TREE_OPERAND (expr, 0));
02067 break;
02068
02069
02070
02071 case SCOPE_REF:
02072 write_type (TREE_OPERAND (expr, 0));
02073 if (TREE_CODE (TREE_OPERAND (expr, 1)) == IDENTIFIER_NODE)
02074 write_source_name (TREE_OPERAND (expr, 1));
02075 else
02076 {
02077
02078
02079 G.need_abi_warning = 1;
02080 write_encoding (TREE_OPERAND (expr, 1));
02081 }
02082 break;
02083
02084 default:
02085 for (i = 0; i < TREE_CODE_LENGTH (code); ++i)
02086 write_expression (TREE_OPERAND (expr, i));
02087 }
02088 }
02089 }
02090
02091
02092
02093
02094
02095
02096
02097
02098 static void
02099 write_template_arg_literal (value)
02100 tree value;
02101 {
02102 tree type = TREE_TYPE (value);
02103 write_char ('L');
02104 write_type (type);
02105
02106 if (TREE_CODE (value) == CONST_DECL)
02107 write_integer_cst (DECL_INITIAL (value));
02108 else if (TREE_CODE (value) == INTEGER_CST)
02109 {
02110 if (same_type_p (type, boolean_type_node))
02111 {
02112 if (value == boolean_false_node || integer_zerop (value))
02113 write_unsigned_number (0);
02114 else if (value == boolean_true_node)
02115 write_unsigned_number (1);
02116 else
02117 abort ();
02118 }
02119 else
02120 write_integer_cst (value);
02121 }
02122 else if (TREE_CODE (value) == REAL_CST)
02123 write_real_cst (value);
02124 else
02125 abort ();
02126
02127 write_char ('E');
02128 }
02129
02130
02131
02132
02133
02134
02135
02136
02137 static void
02138 write_template_arg (node)
02139 tree node;
02140 {
02141 enum tree_code code = TREE_CODE (node);
02142
02143 MANGLE_TRACE_TREE ("template-arg", node);
02144
02145
02146
02147 if (code == TREE_LIST)
02148 {
02149 node = TREE_VALUE (node);
02150
02151 if (DECL_P (node))
02152 {
02153 node = TREE_TYPE (node);
02154 code = TREE_CODE (node);
02155 }
02156 }
02157
02158 if (TYPE_P (node))
02159 write_type (node);
02160 else if (code == TEMPLATE_DECL)
02161
02162 write_template_template_arg (node);
02163 else if ((TREE_CODE_CLASS (code) == 'c' && code != PTRMEM_CST)
02164 || (abi_version_at_least (2) && code == CONST_DECL))
02165 write_template_arg_literal (node);
02166 else if (DECL_P (node))
02167 {
02168
02169
02170 if (code == CONST_DECL)
02171 G.need_abi_warning = 1;
02172 write_char ('L');
02173 write_char ('Z');
02174 write_encoding (node);
02175 write_char ('E');
02176 }
02177 else
02178 {
02179
02180 write_char ('X');
02181 write_expression (node);
02182 write_char ('E');
02183 }
02184 }
02185
02186
02187
02188
02189
02190 void
02191 write_template_template_arg (tree decl)
02192 {
02193 MANGLE_TRACE_TREE ("template-template-arg", decl);
02194
02195 if (find_substitution (decl))
02196 return;
02197 write_name (decl, 0);
02198 add_substitution (decl);
02199 }
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211 static void
02212 write_array_type (type)
02213 tree type;
02214 {
02215 write_char ('A');
02216 if (TYPE_DOMAIN (type))
02217 {
02218 tree index_type;
02219 tree max;
02220
02221 index_type = TYPE_DOMAIN (type);
02222
02223
02224 max = TYPE_MAX_VALUE (index_type);
02225 if (TREE_CODE (max) == INTEGER_CST)
02226 {
02227
02228
02229 max = size_binop (PLUS_EXPR, max, size_one_node);
02230 write_unsigned_number (tree_low_cst (max, 1));
02231 }
02232 else
02233 write_expression (TREE_OPERAND (max, 0));
02234 }
02235 write_char ('_');
02236 write_type (TREE_TYPE (type));
02237 }
02238
02239
02240
02241
02242
02243
02244 static void
02245 write_pointer_to_member_type (type)
02246 tree type;
02247 {
02248 write_char ('M');
02249 write_type (TYPE_PTRMEM_CLASS_TYPE (type));
02250 write_type (TYPE_PTRMEM_POINTED_TO_TYPE (type));
02251 }
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266 static void
02267 write_template_param (parm)
02268 tree parm;
02269 {
02270 int parm_index;
02271 int parm_level;
02272 tree parm_type = NULL_TREE;
02273
02274 MANGLE_TRACE_TREE ("template-parm", parm);
02275
02276 switch (TREE_CODE (parm))
02277 {
02278 case TEMPLATE_TYPE_PARM:
02279 case TEMPLATE_TEMPLATE_PARM:
02280 case BOUND_TEMPLATE_TEMPLATE_PARM:
02281 parm_index = TEMPLATE_TYPE_IDX (parm);
02282 parm_level = TEMPLATE_TYPE_LEVEL (parm);
02283 break;
02284
02285 case TEMPLATE_PARM_INDEX:
02286 parm_index = TEMPLATE_PARM_IDX (parm);
02287 parm_level = TEMPLATE_PARM_LEVEL (parm);
02288 parm_type = TREE_TYPE (TEMPLATE_PARM_DECL (parm));
02289 break;
02290
02291 default:
02292 abort ();
02293 }
02294
02295 write_char ('T');
02296
02297
02298 if (parm_index > 0)
02299 write_unsigned_number (parm_index - 1);
02300 write_char ('_');
02301 }
02302
02303
02304
02305
02306
02307 static void
02308 write_template_template_param (parm)
02309 tree parm;
02310 {
02311 tree template = NULL_TREE;
02312
02313
02314
02315
02316 if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
02317 {
02318 template
02319 = TI_TEMPLATE (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm));
02320 if (find_substitution (template))
02321 return;
02322 }
02323
02324
02325
02326 write_template_param (parm);
02327 if (template)
02328 add_substitution (template);
02329 }
02330
02331
02332
02333
02334
02335
02336 static void
02337 write_substitution (seq_id)
02338 int seq_id;
02339 {
02340 MANGLE_TRACE ("substitution", "");
02341
02342 write_char ('S');
02343 if (seq_id > 0)
02344 write_number (seq_id - 1, 1, 36);
02345 write_char ('_');
02346 }
02347
02348
02349
02350 static inline void
02351 start_mangling (tree entity)
02352 {
02353 G.entity = entity;
02354 G.need_abi_warning = false;
02355 VARRAY_TREE_INIT (G.substitutions, 1, "mangling substitutions");
02356 obstack_free (&G.name_obstack, obstack_base (&G.name_obstack));
02357 }
02358
02359
02360
02361
02362
02363 static inline const char *
02364 finish_mangling (bool warn)
02365 {
02366 if (warn_abi && warn && G.need_abi_warning)
02367 warning ("the mangled name of `%D' will change in a future "
02368 "version of GCC",
02369 G.entity);
02370
02371
02372 G.substitutions = 0;
02373
02374
02375 write_char ('\0');
02376
02377 return (const char *) obstack_base (&G.name_obstack);
02378 }
02379
02380
02381
02382 void
02383 init_mangle ()
02384 {
02385 gcc_obstack_init (&G.name_obstack);
02386
02387
02388
02389 subst_identifiers[SUBID_ALLOCATOR] = get_identifier ("allocator");
02390 subst_identifiers[SUBID_BASIC_STRING] = get_identifier ("basic_string");
02391 subst_identifiers[SUBID_CHAR_TRAITS] = get_identifier ("char_traits");
02392 subst_identifiers[SUBID_BASIC_ISTREAM] = get_identifier ("basic_istream");
02393 subst_identifiers[SUBID_BASIC_OSTREAM] = get_identifier ("basic_ostream");
02394 subst_identifiers[SUBID_BASIC_IOSTREAM] = get_identifier ("basic_iostream");
02395 }
02396
02397
02398
02399 static const char *
02400 mangle_decl_string (decl)
02401 tree decl;
02402 {
02403 const char *result;
02404
02405 start_mangling (decl);
02406
02407 if (TREE_CODE (decl) == TYPE_DECL)
02408 write_type (TREE_TYPE (decl));
02409 else if (
02410 (DECL_EXTERN_C_FUNCTION_P (decl)
02411
02412 && !DECL_OVERLOADED_OPERATOR_P (decl))
02413
02414 || (TREE_CODE (decl) == VAR_DECL
02415 && CP_DECL_CONTEXT (decl) == global_namespace)
02416
02417 || (TREE_CODE (decl) == VAR_DECL
02418 && DECL_EXTERN_C_P (decl)))
02419 write_string (IDENTIFIER_POINTER (DECL_NAME (decl)));
02420 else
02421 {
02422 write_mangled_name (decl);
02423 if (DECL_LANG_SPECIFIC (decl)
02424 && (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)
02425 || DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)))
02426
02427
02428
02429 write_string (" *INTERNAL* ");
02430 }
02431
02432 result = finish_mangling (true);
02433 if (DEBUG_MANGLE)
02434 fprintf (stderr, "mangle_decl_string = '%s'\n\n", result);
02435 return result;
02436 }
02437
02438
02439
02440 void
02441 mangle_decl (decl)
02442 tree decl;
02443 {
02444 tree id = get_identifier (mangle_decl_string (decl));
02445
02446 SET_DECL_ASSEMBLER_NAME (decl, id);
02447 }
02448
02449
02450
02451 const char *
02452 mangle_type_string (type)
02453 tree type;
02454 {
02455 const char *result;
02456
02457 start_mangling (type);
02458 write_type (type);
02459 result = finish_mangling (false);
02460 if (DEBUG_MANGLE)
02461 fprintf (stderr, "mangle_type_string = '%s'\n\n", result);
02462 return result;
02463 }
02464
02465
02466
02467 tree
02468 mangle_type (type)
02469 tree type;
02470 {
02471 return get_identifier (mangle_type_string (type));
02472 }
02473
02474
02475
02476
02477
02478 static tree
02479 mangle_special_for_type (type, code)
02480 tree type;
02481 const char *code;
02482 {
02483 const char *result;
02484
02485
02486
02487 start_mangling (type);
02488
02489
02490 write_string ("_Z");
02491 write_string (code);
02492
02493
02494 write_type (type);
02495 result = finish_mangling (false);
02496
02497 if (DEBUG_MANGLE)
02498 fprintf (stderr, "mangle_special_for_type = %s\n\n", result);
02499
02500 return get_identifier (result);
02501 }
02502
02503
02504
02505
02506 tree
02507 mangle_typeinfo_for_type (type)
02508 tree type;
02509 {
02510 return mangle_special_for_type (type, "TI");
02511 }
02512
02513
02514
02515
02516 tree
02517 mangle_typeinfo_string_for_type (type)
02518 tree type;
02519 {
02520 return mangle_special_for_type (type, "TS");
02521 }
02522
02523
02524
02525 tree
02526 mangle_vtbl_for_type (type)
02527 tree type;
02528 {
02529 return mangle_special_for_type (type, "TV");
02530 }
02531
02532
02533
02534 tree
02535 mangle_vtt_for_type (type)
02536 tree type;
02537 {
02538 return mangle_special_for_type (type, "TT");
02539 }
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554
02555 tree
02556 mangle_ctor_vtbl_for_type (type, binfo)
02557 tree type;
02558 tree binfo;
02559 {
02560 const char *result;
02561
02562 start_mangling (type);
02563
02564 write_string ("_Z");
02565 write_string ("TC");
02566 write_type (type);
02567 write_integer_cst (BINFO_OFFSET (binfo));
02568 write_char ('_');
02569 write_type (BINFO_TYPE (binfo));
02570
02571 result = finish_mangling (false);
02572 if (DEBUG_MANGLE)
02573 fprintf (stderr, "mangle_ctor_vtbl_for_type = %s\n\n", result);
02574 return get_identifier (result);
02575 }
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587 tree
02588 mangle_thunk (fn_decl, offset, vcall_offset)
02589 tree fn_decl;
02590 tree offset;
02591 tree vcall_offset;
02592 {
02593 const char *result;
02594
02595 start_mangling (fn_decl);
02596
02597 write_string ("_Z");
02598
02599
02600 write_char ('T');
02601 if (vcall_offset != 0)
02602 write_char ('v');
02603 else
02604 write_char ('h');
02605
02606
02607 write_integer_cst (offset);
02608 write_char ('_');
02609
02610
02611 if (vcall_offset)
02612 {
02613
02614 write_integer_cst (vcall_offset);
02615 write_char ('_');
02616 }
02617
02618
02619 write_encoding (fn_decl);
02620
02621 result = finish_mangling (false);
02622 if (DEBUG_MANGLE)
02623 fprintf (stderr, "mangle_thunk = %s\n\n", result);
02624 return get_identifier (result);
02625 }
02626
02627
02628
02629
02630
02631 static GTY ((param_is (union tree_node))) htab_t conv_type_names;
02632
02633
02634
02635 static hashval_t
02636 hash_type (const void *val)
02637 {
02638 return htab_hash_pointer (TREE_PURPOSE ((tree) val));
02639 }
02640
02641
02642
02643 static int
02644 compare_type (const void *val1, const void *val2)
02645 {
02646 return TREE_PURPOSE ((tree) val1) == (tree) val2;
02647 }
02648
02649
02650
02651
02652
02653 tree
02654 mangle_conv_op_name_for_type (const tree type)
02655 {
02656 void **slot;
02657 tree identifier;
02658 char buffer[64];
02659
02660 if (conv_type_names == NULL)
02661 conv_type_names = htab_create_ggc (31, &hash_type, &compare_type, NULL);
02662
02663 slot = htab_find_slot_with_hash (conv_type_names, type,
02664 htab_hash_pointer (type), INSERT);
02665 if (*slot)
02666 return TREE_VALUE ((tree) *slot);
02667
02668
02669 sprintf (buffer, "operator %lu",
02670 (unsigned long) htab_elements (conv_type_names));
02671 identifier = get_identifier (buffer);
02672 *slot = build_tree_list (type, identifier);
02673
02674
02675 IDENTIFIER_OPNAME_P (identifier) = 1;
02676 IDENTIFIER_TYPENAME_P (identifier) = 1;
02677
02678
02679 TREE_TYPE (identifier) = type;
02680
02681 return identifier;
02682 }
02683
02684
02685
02686
02687 tree
02688 mangle_guard_variable (variable)
02689 tree variable;
02690 {
02691 start_mangling (variable);
02692 write_string ("_ZGV");
02693 if (strncmp (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR", 4) == 0)
02694
02695
02696 write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4);
02697 else
02698 write_name (variable, 0);
02699 return get_identifier (finish_mangling (false));
02700 }
02701
02702
02703
02704
02705
02706 tree
02707 mangle_ref_init_variable (variable)
02708 tree variable;
02709 {
02710 start_mangling (variable);
02711 write_string ("_ZGR");
02712 write_name (variable, 0);
02713 return get_identifier (finish_mangling (false));
02714 }
02715
02716
02717
02718
02719
02720
02721 static void
02722 write_java_integer_type_codes (type)
02723 tree type;
02724 {
02725 if (type == java_int_type_node)
02726 write_char ('i');
02727 else if (type == java_short_type_node)
02728 write_char ('s');
02729 else if (type == java_byte_type_node)
02730 write_char ('c');
02731 else if (type == java_char_type_node)
02732 write_char ('w');
02733 else if (type == java_long_type_node)
02734 write_char ('x');
02735 else if (type == java_boolean_type_node)
02736 write_char ('b');
02737 else
02738 abort ();
02739 }
02740
02741 #include "gt-cp-mangle.h"