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