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