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 #ifdef HAVE_CONFIG_H
00047 #include "config.h"
00048 #endif
00049
00050 #include "safe-ctype.h"
00051
00052 #include <sys/types.h>
00053 #include <string.h>
00054 #include <stdio.h>
00055
00056 #ifdef HAVE_STDLIB_H
00057 #include <stdlib.h>
00058 #else
00059 char * malloc ();
00060 char * realloc ();
00061 #endif
00062
00063 #include <demangle.h>
00064 #undef CURRENT_DEMANGLING_STYLE
00065 #define CURRENT_DEMANGLING_STYLE work->options
00066
00067 #include "libiberty.h"
00068
00069 static char *ada_demangle PARAMS ((const char *, int));
00070
00071 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
00072
00073
00074
00075 #define INTBUF_SIZE 32
00076
00077 extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 #if !defined (CPLUS_MARKER)
00096 #define CPLUS_MARKER '$'
00097 #endif
00098
00099 enum demangling_styles current_demangling_style = auto_demangling;
00100
00101 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
00102
00103 static char char_str[2] = { '\000', '\000' };
00104
00105 void
00106 set_cplus_marker_for_demangling (ch)
00107 int ch;
00108 {
00109 cplus_markers[0] = ch;
00110 }
00111
00112 typedef struct string
00113 {
00114 char *b;
00115 char *p;
00116 char *e;
00117 } string;
00118
00119
00120
00121
00122 struct work_stuff
00123 {
00124 int options;
00125 char **typevec;
00126 char **ktypevec;
00127 char **btypevec;
00128 int numk;
00129 int numb;
00130 int ksize;
00131 int bsize;
00132 int ntypes;
00133 int typevec_size;
00134 int constructor;
00135 int destructor;
00136 int static_type;
00137 int temp_start;
00138 int type_quals;
00139 int dllimported;
00140 char **tmpl_argvec;
00141 int ntmpl_args;
00142 int forgetting_types;
00143
00144 string* previous_argument;
00145 int nrepeats;
00146
00147 };
00148
00149 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
00150 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
00151
00152 static const struct optable
00153 {
00154 const char *const in;
00155 const char *const out;
00156 const int flags;
00157 } optable[] = {
00158 {"nw", " new", DMGL_ANSI},
00159 {"dl", " delete", DMGL_ANSI},
00160 {"new", " new", 0},
00161 {"delete", " delete", 0},
00162 {"vn", " new []", DMGL_ANSI},
00163 {"vd", " delete []", DMGL_ANSI},
00164 {"as", "=", DMGL_ANSI},
00165 {"ne", "!=", DMGL_ANSI},
00166 {"eq", "==", DMGL_ANSI},
00167 {"ge", ">=", DMGL_ANSI},
00168 {"gt", ">", DMGL_ANSI},
00169 {"le", "<=", DMGL_ANSI},
00170 {"lt", "<", DMGL_ANSI},
00171 {"plus", "+", 0},
00172 {"pl", "+", DMGL_ANSI},
00173 {"apl", "+=", DMGL_ANSI},
00174 {"minus", "-", 0},
00175 {"mi", "-", DMGL_ANSI},
00176 {"ami", "-=", DMGL_ANSI},
00177 {"mult", "*", 0},
00178 {"ml", "*", DMGL_ANSI},
00179 {"amu", "*=", DMGL_ANSI},
00180 {"aml", "*=", DMGL_ANSI},
00181 {"convert", "+", 0},
00182 {"negate", "-", 0},
00183 {"trunc_mod", "%", 0},
00184 {"md", "%", DMGL_ANSI},
00185 {"amd", "%=", DMGL_ANSI},
00186 {"trunc_div", "/", 0},
00187 {"dv", "/", DMGL_ANSI},
00188 {"adv", "/=", DMGL_ANSI},
00189 {"truth_andif", "&&", 0},
00190 {"aa", "&&", DMGL_ANSI},
00191 {"truth_orif", "||", 0},
00192 {"oo", "||", DMGL_ANSI},
00193 {"truth_not", "!", 0},
00194 {"nt", "!", DMGL_ANSI},
00195 {"postincrement","++", 0},
00196 {"pp", "++", DMGL_ANSI},
00197 {"postdecrement","--", 0},
00198 {"mm", "--", DMGL_ANSI},
00199 {"bit_ior", "|", 0},
00200 {"or", "|", DMGL_ANSI},
00201 {"aor", "|=", DMGL_ANSI},
00202 {"bit_xor", "^", 0},
00203 {"er", "^", DMGL_ANSI},
00204 {"aer", "^=", DMGL_ANSI},
00205 {"bit_and", "&", 0},
00206 {"ad", "&", DMGL_ANSI},
00207 {"aad", "&=", DMGL_ANSI},
00208 {"bit_not", "~", 0},
00209 {"co", "~", DMGL_ANSI},
00210 {"call", "()", 0},
00211 {"cl", "()", DMGL_ANSI},
00212 {"alshift", "<<", 0},
00213 {"ls", "<<", DMGL_ANSI},
00214 {"als", "<<=", DMGL_ANSI},
00215 {"arshift", ">>", 0},
00216 {"rs", ">>", DMGL_ANSI},
00217 {"ars", ">>=", DMGL_ANSI},
00218 {"component", "->", 0},
00219 {"pt", "->", DMGL_ANSI},
00220 {"rf", "->", DMGL_ANSI},
00221 {"indirect", "*", 0},
00222 {"method_call", "->()", 0},
00223 {"addr", "&", 0},
00224 {"array", "[]", 0},
00225 {"vc", "[]", DMGL_ANSI},
00226 {"compound", ", ", 0},
00227 {"cm", ", ", DMGL_ANSI},
00228 {"cond", "?:", 0},
00229 {"cn", "?:", DMGL_ANSI},
00230 {"max", ">?", 0},
00231 {"mx", ">?", DMGL_ANSI},
00232 {"min", "<?", 0},
00233 {"mn", "<?", DMGL_ANSI},
00234 {"nop", "", 0},
00235 {"rm", "->*", DMGL_ANSI},
00236 {"sz", "sizeof ", DMGL_ANSI}
00237 };
00238
00239
00240
00241
00242 typedef enum type_kind_t
00243 {
00244 tk_none,
00245 tk_pointer,
00246 tk_reference,
00247 tk_integral,
00248 tk_bool,
00249 tk_char,
00250 tk_real
00251 } type_kind_t;
00252
00253 const struct demangler_engine libiberty_demanglers[] =
00254 {
00255 {
00256 NO_DEMANGLING_STYLE_STRING,
00257 no_demangling,
00258 "Demangling disabled"
00259 }
00260 ,
00261 {
00262 AUTO_DEMANGLING_STYLE_STRING,
00263 auto_demangling,
00264 "Automatic selection based on executable"
00265 }
00266 ,
00267 {
00268 GNU_DEMANGLING_STYLE_STRING,
00269 gnu_demangling,
00270 "GNU (g++) style demangling"
00271 }
00272 ,
00273 {
00274 LUCID_DEMANGLING_STYLE_STRING,
00275 lucid_demangling,
00276 "Lucid (lcc) style demangling"
00277 }
00278 ,
00279 {
00280 ARM_DEMANGLING_STYLE_STRING,
00281 arm_demangling,
00282 "ARM style demangling"
00283 }
00284 ,
00285 {
00286 HP_DEMANGLING_STYLE_STRING,
00287 hp_demangling,
00288 "HP (aCC) style demangling"
00289 }
00290 ,
00291 {
00292 EDG_DEMANGLING_STYLE_STRING,
00293 edg_demangling,
00294 "EDG style demangling"
00295 }
00296 ,
00297 {
00298 GNU_V3_DEMANGLING_STYLE_STRING,
00299 gnu_v3_demangling,
00300 "GNU (g++) V3 ABI-style demangling"
00301 }
00302 ,
00303 {
00304 JAVA_DEMANGLING_STYLE_STRING,
00305 java_demangling,
00306 "Java style demangling"
00307 }
00308 ,
00309 {
00310 GNAT_DEMANGLING_STYLE_STRING,
00311 gnat_demangling,
00312 "GNAT style demangling"
00313 }
00314 ,
00315 {
00316 NULL, unknown_demangling, NULL
00317 }
00318 };
00319
00320 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
00321 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
00322 string_append(str, " ");}
00323 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
00324
00325
00326
00327 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
00328
00329 #define ARM_VTABLE_STRING "__vtbl__"
00330 #define ARM_VTABLE_STRLEN 8
00331
00332
00333
00334 static void
00335 delete_work_stuff PARAMS ((struct work_stuff *));
00336
00337 static void
00338 delete_non_B_K_work_stuff PARAMS ((struct work_stuff *));
00339
00340 static char *
00341 mop_up PARAMS ((struct work_stuff *, string *, int));
00342
00343 static void
00344 squangle_mop_up PARAMS ((struct work_stuff *));
00345
00346 static void
00347 work_stuff_copy_to_from PARAMS ((struct work_stuff *, struct work_stuff *));
00348
00349 #if 0
00350 static int
00351 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
00352 #endif
00353
00354 static char *
00355 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
00356
00357 static int
00358 demangle_template_template_parm PARAMS ((struct work_stuff *work,
00359 const char **, string *));
00360
00361 static int
00362 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
00363 string *, int, int));
00364
00365 static int
00366 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
00367 const char **));
00368
00369 static int
00370 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
00371
00372 static int
00373 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
00374 int, int));
00375
00376 static int
00377 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
00378
00379 static int
00380 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
00381
00382 static int
00383 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
00384
00385 static int
00386 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
00387
00388 static int
00389 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
00390
00391 static int
00392 arm_special PARAMS ((const char **, string *));
00393
00394 static void
00395 string_need PARAMS ((string *, int));
00396
00397 static void
00398 string_delete PARAMS ((string *));
00399
00400 static void
00401 string_init PARAMS ((string *));
00402
00403 static void
00404 string_clear PARAMS ((string *));
00405
00406 #if 0
00407 static int
00408 string_empty PARAMS ((string *));
00409 #endif
00410
00411 static void
00412 string_append PARAMS ((string *, const char *));
00413
00414 static void
00415 string_appends PARAMS ((string *, string *));
00416
00417 static void
00418 string_appendn PARAMS ((string *, const char *, int));
00419
00420 static void
00421 string_prepend PARAMS ((string *, const char *));
00422
00423 static void
00424 string_prependn PARAMS ((string *, const char *, int));
00425
00426 static void
00427 string_append_template_idx PARAMS ((string *, int));
00428
00429 static int
00430 get_count PARAMS ((const char **, int *));
00431
00432 static int
00433 consume_count PARAMS ((const char **));
00434
00435 static int
00436 consume_count_with_underscores PARAMS ((const char**));
00437
00438 static int
00439 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
00440
00441 static int
00442 demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
00443
00444 static int
00445 do_type PARAMS ((struct work_stuff *, const char **, string *));
00446
00447 static int
00448 do_arg PARAMS ((struct work_stuff *, const char **, string *));
00449
00450 static void
00451 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
00452 const char *));
00453
00454 static int
00455 iterate_demangle_function PARAMS ((struct work_stuff *,
00456 const char **, string *, const char *));
00457
00458 static void
00459 remember_type PARAMS ((struct work_stuff *, const char *, int));
00460
00461 static void
00462 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
00463
00464 static int
00465 register_Btype PARAMS ((struct work_stuff *));
00466
00467 static void
00468 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
00469
00470 static void
00471 forget_types PARAMS ((struct work_stuff *));
00472
00473 static void
00474 forget_B_and_K_types PARAMS ((struct work_stuff *));
00475
00476 static void
00477 string_prepends PARAMS ((string *, string *));
00478
00479 static int
00480 demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
00481 string*, type_kind_t));
00482
00483 static int
00484 do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *));
00485
00486 static int
00487 do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *));
00488
00489 static int
00490 snarf_numeric_literal PARAMS ((const char **, string *));
00491
00492
00493
00494
00495
00496 #define TYPE_UNQUALIFIED 0x0
00497 #define TYPE_QUAL_CONST 0x1
00498 #define TYPE_QUAL_VOLATILE 0x2
00499 #define TYPE_QUAL_RESTRICT 0x4
00500
00501 static int
00502 code_for_qualifier PARAMS ((int));
00503
00504 static const char*
00505 qualifier_string PARAMS ((int));
00506
00507 static const char*
00508 demangle_qualifier PARAMS ((int));
00509
00510 static int
00511 demangle_expression PARAMS ((struct work_stuff *, const char **, string *,
00512 type_kind_t));
00513
00514 static int
00515 demangle_integral_value PARAMS ((struct work_stuff *, const char **,
00516 string *));
00517
00518 static int
00519 demangle_real_value PARAMS ((struct work_stuff *, const char **, string *));
00520
00521 static void
00522 demangle_arm_hp_template PARAMS ((struct work_stuff *, const char **, int,
00523 string *));
00524
00525 static void
00526 recursively_demangle PARAMS ((struct work_stuff *, const char **, string *,
00527 int));
00528
00529 static void
00530 grow_vect PARAMS ((char **, size_t *, size_t, int));
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 static int
00541 consume_count (type)
00542 const char **type;
00543 {
00544 int count = 0;
00545
00546 if (! ISDIGIT ((unsigned char)**type))
00547 return -1;
00548
00549 while (ISDIGIT ((unsigned char)**type))
00550 {
00551 count *= 10;
00552
00553
00554
00555
00556
00557
00558 if ((count % 10) != 0)
00559 {
00560 while (ISDIGIT ((unsigned char) **type))
00561 (*type)++;
00562 return -1;
00563 }
00564
00565 count += **type - '0';
00566 (*type)++;
00567 }
00568
00569 if (count < 0)
00570 count = -1;
00571
00572 return (count);
00573 }
00574
00575
00576
00577
00578
00579
00580 static int
00581 consume_count_with_underscores (mangled)
00582 const char **mangled;
00583 {
00584 int idx;
00585
00586 if (**mangled == '_')
00587 {
00588 (*mangled)++;
00589 if (!ISDIGIT ((unsigned char)**mangled))
00590 return -1;
00591
00592 idx = consume_count (mangled);
00593 if (**mangled != '_')
00594
00595 return -1;
00596
00597 (*mangled)++;
00598 }
00599 else
00600 {
00601 if (**mangled < '0' || **mangled > '9')
00602 return -1;
00603
00604 idx = **mangled - '0';
00605 (*mangled)++;
00606 }
00607
00608 return idx;
00609 }
00610
00611
00612
00613
00614 static int
00615 code_for_qualifier (c)
00616 int c;
00617 {
00618 switch (c)
00619 {
00620 case 'C':
00621 return TYPE_QUAL_CONST;
00622
00623 case 'V':
00624 return TYPE_QUAL_VOLATILE;
00625
00626 case 'u':
00627 return TYPE_QUAL_RESTRICT;
00628
00629 default:
00630 break;
00631 }
00632
00633
00634 abort ();
00635 }
00636
00637
00638
00639
00640 static const char*
00641 qualifier_string (type_quals)
00642 int type_quals;
00643 {
00644 switch (type_quals)
00645 {
00646 case TYPE_UNQUALIFIED:
00647 return "";
00648
00649 case TYPE_QUAL_CONST:
00650 return "const";
00651
00652 case TYPE_QUAL_VOLATILE:
00653 return "volatile";
00654
00655 case TYPE_QUAL_RESTRICT:
00656 return "__restrict";
00657
00658 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
00659 return "const volatile";
00660
00661 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
00662 return "const __restrict";
00663
00664 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
00665 return "volatile __restrict";
00666
00667 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
00668 return "const volatile __restrict";
00669
00670 default:
00671 break;
00672 }
00673
00674
00675 abort ();
00676 }
00677
00678
00679
00680
00681
00682 static const char*
00683 demangle_qualifier (c)
00684 int c;
00685 {
00686 return qualifier_string (code_for_qualifier (c));
00687 }
00688
00689 int
00690 cplus_demangle_opname (opname, result, options)
00691 const char *opname;
00692 char *result;
00693 int options;
00694 {
00695 int len, len1, ret;
00696 string type;
00697 struct work_stuff work[1];
00698 const char *tem;
00699
00700 len = strlen(opname);
00701 result[0] = '\0';
00702 ret = 0;
00703 memset ((char *) work, 0, sizeof (work));
00704 work->options = options;
00705
00706 if (opname[0] == '_' && opname[1] == '_'
00707 && opname[2] == 'o' && opname[3] == 'p')
00708 {
00709
00710
00711 tem = opname + 4;
00712 if (do_type (work, &tem, &type))
00713 {
00714 strcat (result, "operator ");
00715 strncat (result, type.b, type.p - type.b);
00716 string_delete (&type);
00717 ret = 1;
00718 }
00719 }
00720 else if (opname[0] == '_' && opname[1] == '_'
00721 && ISLOWER((unsigned char)opname[2])
00722 && ISLOWER((unsigned char)opname[3]))
00723 {
00724 if (opname[4] == '\0')
00725 {
00726
00727 size_t i;
00728 for (i = 0; i < ARRAY_SIZE (optable); i++)
00729 {
00730 if (strlen (optable[i].in) == 2
00731 && memcmp (optable[i].in, opname + 2, 2) == 0)
00732 {
00733 strcat (result, "operator");
00734 strcat (result, optable[i].out);
00735 ret = 1;
00736 break;
00737 }
00738 }
00739 }
00740 else
00741 {
00742 if (opname[2] == 'a' && opname[5] == '\0')
00743 {
00744
00745 size_t i;
00746 for (i = 0; i < ARRAY_SIZE (optable); i++)
00747 {
00748 if (strlen (optable[i].in) == 3
00749 && memcmp (optable[i].in, opname + 2, 3) == 0)
00750 {
00751 strcat (result, "operator");
00752 strcat (result, optable[i].out);
00753 ret = 1;
00754 break;
00755 }
00756 }
00757 }
00758 }
00759 }
00760 else if (len >= 3
00761 && opname[0] == 'o'
00762 && opname[1] == 'p'
00763 && strchr (cplus_markers, opname[2]) != NULL)
00764 {
00765
00766 if (len >= 10
00767 && memcmp (opname + 3, "assign_", 7) == 0)
00768 {
00769 size_t i;
00770 for (i = 0; i < ARRAY_SIZE (optable); i++)
00771 {
00772 len1 = len - 10;
00773 if ((int) strlen (optable[i].in) == len1
00774 && memcmp (optable[i].in, opname + 10, len1) == 0)
00775 {
00776 strcat (result, "operator");
00777 strcat (result, optable[i].out);
00778 strcat (result, "=");
00779 ret = 1;
00780 break;
00781 }
00782 }
00783 }
00784 else
00785 {
00786 size_t i;
00787 for (i = 0; i < ARRAY_SIZE (optable); i++)
00788 {
00789 len1 = len - 3;
00790 if ((int) strlen (optable[i].in) == len1
00791 && memcmp (optable[i].in, opname + 3, len1) == 0)
00792 {
00793 strcat (result, "operator");
00794 strcat (result, optable[i].out);
00795 ret = 1;
00796 break;
00797 }
00798 }
00799 }
00800 }
00801 else if (len >= 5 && memcmp (opname, "type", 4) == 0
00802 && strchr (cplus_markers, opname[4]) != NULL)
00803 {
00804
00805 tem = opname + 5;
00806 if (do_type (work, &tem, &type))
00807 {
00808 strcat (result, "operator ");
00809 strncat (result, type.b, type.p - type.b);
00810 string_delete (&type);
00811 ret = 1;
00812 }
00813 }
00814 squangle_mop_up (work);
00815 return ret;
00816
00817 }
00818
00819
00820
00821
00822
00823
00824
00825 const char *
00826 cplus_mangle_opname (opname, options)
00827 const char *opname;
00828 int options;
00829 {
00830 size_t i;
00831 int len;
00832
00833 len = strlen (opname);
00834 for (i = 0; i < ARRAY_SIZE (optable); i++)
00835 {
00836 if ((int) strlen (optable[i].out) == len
00837 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
00838 && memcmp (optable[i].out, opname, len) == 0)
00839 return optable[i].in;
00840 }
00841 return (0);
00842 }
00843
00844
00845
00846
00847 enum demangling_styles
00848 cplus_demangle_set_style (style)
00849 enum demangling_styles style;
00850 {
00851 const struct demangler_engine *demangler = libiberty_demanglers;
00852
00853 for (; demangler->demangling_style != unknown_demangling; ++demangler)
00854 if (style == demangler->demangling_style)
00855 {
00856 current_demangling_style = style;
00857 return current_demangling_style;
00858 }
00859
00860 return unknown_demangling;
00861 }
00862
00863
00864
00865 enum demangling_styles
00866 cplus_demangle_name_to_style (name)
00867 const char *name;
00868 {
00869 const struct demangler_engine *demangler = libiberty_demanglers;
00870
00871 for (; demangler->demangling_style != unknown_demangling; ++demangler)
00872 if (strcmp (name, demangler->demangling_style_name) == 0)
00873 return demangler->demangling_style;
00874
00875 return unknown_demangling;
00876 }
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906 char *
00907 cplus_demangle (mangled, options)
00908 const char *mangled;
00909 int options;
00910 {
00911 char *ret;
00912 struct work_stuff work[1];
00913
00914 if (current_demangling_style == no_demangling)
00915 return xstrdup (mangled);
00916
00917 memset ((char *) work, 0, sizeof (work));
00918 work->options = options;
00919 if ((work->options & DMGL_STYLE_MASK) == 0)
00920 work->options |= (int) current_demangling_style & DMGL_STYLE_MASK;
00921
00922
00923 if (GNU_V3_DEMANGLING || AUTO_DEMANGLING)
00924 {
00925 ret = cplus_demangle_v3 (mangled, work->options);
00926 if (ret || GNU_V3_DEMANGLING)
00927 return ret;
00928 }
00929
00930 if (JAVA_DEMANGLING)
00931 {
00932 ret = java_demangle_v3 (mangled);
00933 if (ret)
00934 return ret;
00935 }
00936
00937 if (GNAT_DEMANGLING)
00938 return ada_demangle(mangled,options);
00939
00940 ret = internal_cplus_demangle (work, mangled);
00941 squangle_mop_up (work);
00942 return (ret);
00943 }
00944
00945
00946
00947
00948
00949
00950 static void
00951 grow_vect (old_vect, size, min_size, element_size)
00952 char **old_vect;
00953 size_t *size;
00954 size_t min_size;
00955 int element_size;
00956 {
00957 if (*size < min_size)
00958 {
00959 *size *= 2;
00960 if (*size < min_size)
00961 *size = min_size;
00962 *old_vect = (void *) xrealloc (*old_vect, *size * element_size);
00963 }
00964 }
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974 static char *
00975 ada_demangle (mangled, option)
00976 const char *mangled;
00977 int option ATTRIBUTE_UNUSED;
00978 {
00979 int i, j;
00980 int len0;
00981 const char* p;
00982 char *demangled = NULL;
00983 int changed;
00984 size_t demangled_size = 0;
00985
00986 changed = 0;
00987
00988 if (strncmp (mangled, "_ada_", 5) == 0)
00989 {
00990 mangled += 5;
00991 changed = 1;
00992 }
00993
00994 if (mangled[0] == '_' || mangled[0] == '<')
00995 goto Suppress;
00996
00997 p = strstr (mangled, "___");
00998 if (p == NULL)
00999 len0 = strlen (mangled);
01000 else
01001 {
01002 if (p[3] == 'X')
01003 {
01004 len0 = p - mangled;
01005 changed = 1;
01006 }
01007 else
01008 goto Suppress;
01009 }
01010
01011
01012 grow_vect (&demangled,
01013 &demangled_size, 2 * len0 + 1,
01014 sizeof (char));
01015
01016 if (ISDIGIT ((unsigned char) mangled[len0 - 1])) {
01017 for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1)
01018 ;
01019 if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_')
01020 {
01021 len0 = i - 1;
01022 changed = 1;
01023 }
01024 else if (mangled[i] == '$')
01025 {
01026 len0 = i;
01027 changed = 1;
01028 }
01029 }
01030
01031 for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]);
01032 i += 1, j += 1)
01033 demangled[j] = mangled[i];
01034
01035 while (i < len0)
01036 {
01037 if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_')
01038 {
01039 demangled[j] = '.';
01040 changed = 1;
01041 i += 2; j += 1;
01042 }
01043 else
01044 {
01045 demangled[j] = mangled[i];
01046 i += 1; j += 1;
01047 }
01048 }
01049 demangled[j] = '\000';
01050
01051 for (i = 0; demangled[i] != '\0'; i += 1)
01052 if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ')
01053 goto Suppress;
01054
01055 if (! changed)
01056 return NULL;
01057 else
01058 return demangled;
01059
01060 Suppress:
01061 grow_vect (&demangled,
01062 &demangled_size, strlen (mangled) + 3,
01063 sizeof (char));
01064
01065 if (mangled[0] == '<')
01066 strcpy (demangled, mangled);
01067 else
01068 sprintf (demangled, "<%s>", mangled);
01069
01070 return demangled;
01071 }
01072
01073
01074
01075
01076
01077
01078
01079 static char *
01080 internal_cplus_demangle (work, mangled)
01081 struct work_stuff *work;
01082 const char *mangled;
01083 {
01084
01085 string decl;
01086 int success = 0;
01087 char *demangled = NULL;
01088 int s1, s2, s3, s4;
01089 s1 = work->constructor;
01090 s2 = work->destructor;
01091 s3 = work->static_type;
01092 s4 = work->type_quals;
01093 work->constructor = work->destructor = 0;
01094 work->type_quals = TYPE_UNQUALIFIED;
01095 work->dllimported = 0;
01096
01097 if ((mangled != NULL) && (*mangled != '\0'))
01098 {
01099 string_init (&decl);
01100
01101
01102
01103
01104
01105
01106
01107
01108 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
01109 {
01110 success = gnu_special (work, &mangled, &decl);
01111 }
01112 if (!success)
01113 {
01114 success = demangle_prefix (work, &mangled, &decl);
01115 }
01116 if (success && (*mangled != '\0'))
01117 {
01118 success = demangle_signature (work, &mangled, &decl);
01119 }
01120 if (work->constructor == 2)
01121 {
01122 string_prepend (&decl, "global constructors keyed to ");
01123 work->constructor = 0;
01124 }
01125 else if (work->destructor == 2)
01126 {
01127 string_prepend (&decl, "global destructors keyed to ");
01128 work->destructor = 0;
01129 }
01130 else if (work->dllimported == 1)
01131 {
01132 string_prepend (&decl, "import stub for ");
01133 work->dllimported = 0;
01134 }
01135 demangled = mop_up (work, &decl, success);
01136 }
01137 work->constructor = s1;
01138 work->destructor = s2;
01139 work->static_type = s3;
01140 work->type_quals = s4;
01141 return demangled;
01142 }
01143
01144
01145
01146 static void
01147 squangle_mop_up (work)
01148 struct work_stuff *work;
01149 {
01150
01151 forget_B_and_K_types (work);
01152 if (work -> btypevec != NULL)
01153 {
01154 free ((char *) work -> btypevec);
01155 }
01156 if (work -> ktypevec != NULL)
01157 {
01158 free ((char *) work -> ktypevec);
01159 }
01160 }
01161
01162
01163
01164
01165 static void
01166 work_stuff_copy_to_from (to, from)
01167 struct work_stuff *to;
01168 struct work_stuff *from;
01169 {
01170 int i;
01171
01172 delete_work_stuff (to);
01173
01174
01175 memcpy (to, from, sizeof (*to));
01176
01177
01178 if (from->typevec_size)
01179 to->typevec
01180 = (char **) xmalloc (from->typevec_size * sizeof (to->typevec[0]));
01181
01182 for (i = 0; i < from->ntypes; i++)
01183 {
01184 int len = strlen (from->typevec[i]) + 1;
01185
01186 to->typevec[i] = xmalloc (len);
01187 memcpy (to->typevec[i], from->typevec[i], len);
01188 }
01189
01190 if (from->ksize)
01191 to->ktypevec
01192 = (char **) xmalloc (from->ksize * sizeof (to->ktypevec[0]));
01193
01194 for (i = 0; i < from->numk; i++)
01195 {
01196 int len = strlen (from->ktypevec[i]) + 1;
01197
01198 to->ktypevec[i] = xmalloc (len);
01199 memcpy (to->ktypevec[i], from->ktypevec[i], len);
01200 }
01201
01202 if (from->bsize)
01203 to->btypevec
01204 = (char **) xmalloc (from->bsize * sizeof (to->btypevec[0]));
01205
01206 for (i = 0; i < from->numb; i++)
01207 {
01208 int len = strlen (from->btypevec[i]) + 1;
01209
01210 to->btypevec[i] = xmalloc (len);
01211 memcpy (to->btypevec[i], from->btypevec[i], len);
01212 }
01213
01214 if (from->ntmpl_args)
01215 to->tmpl_argvec
01216 = (char **) xmalloc (from->ntmpl_args * sizeof (to->tmpl_argvec[0]));
01217
01218 for (i = 0; i < from->ntmpl_args; i++)
01219 {
01220 int len = strlen (from->tmpl_argvec[i]) + 1;
01221
01222 to->tmpl_argvec[i] = xmalloc (len);
01223 memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len);
01224 }
01225
01226 if (from->previous_argument)
01227 {
01228 to->previous_argument = (string*) xmalloc (sizeof (string));
01229 string_init (to->previous_argument);
01230 string_appends (to->previous_argument, from->previous_argument);
01231 }
01232 }
01233
01234
01235
01236
01237 static void
01238 delete_non_B_K_work_stuff (work)
01239 struct work_stuff *work;
01240 {
01241
01242
01243 forget_types (work);
01244 if (work -> typevec != NULL)
01245 {
01246 free ((char *) work -> typevec);
01247 work -> typevec = NULL;
01248 work -> typevec_size = 0;
01249 }
01250 if (work->tmpl_argvec)
01251 {
01252 int i;
01253
01254 for (i = 0; i < work->ntmpl_args; i++)
01255 if (work->tmpl_argvec[i])
01256 free ((char*) work->tmpl_argvec[i]);
01257
01258 free ((char*) work->tmpl_argvec);
01259 work->tmpl_argvec = NULL;
01260 }
01261 if (work->previous_argument)
01262 {
01263 string_delete (work->previous_argument);
01264 free ((char*) work->previous_argument);
01265 work->previous_argument = NULL;
01266 }
01267 }
01268
01269
01270
01271 static void
01272 delete_work_stuff (work)
01273 struct work_stuff *work;
01274 {
01275 delete_non_B_K_work_stuff (work);
01276 squangle_mop_up (work);
01277 }
01278
01279
01280
01281
01282 static char *
01283 mop_up (work, declp, success)
01284 struct work_stuff *work;
01285 string *declp;
01286 int success;
01287 {
01288 char *demangled = NULL;
01289
01290 delete_non_B_K_work_stuff (work);
01291
01292
01293
01294
01295 if (!success)
01296 {
01297 string_delete (declp);
01298 }
01299 else
01300 {
01301 string_appendn (declp, "", 1);
01302 demangled = declp->b;
01303 }
01304 return (demangled);
01305 }
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337 static int
01338 demangle_signature (work, mangled, declp)
01339 struct work_stuff *work;
01340 const char **mangled;
01341 string *declp;
01342 {
01343 int success = 1;
01344 int func_done = 0;
01345 int expect_func = 0;
01346 int expect_return_type = 0;
01347 const char *oldmangled = NULL;
01348 string trawname;
01349 string tname;
01350
01351 while (success && (**mangled != '\0'))
01352 {
01353 switch (**mangled)
01354 {
01355 case 'Q':
01356 oldmangled = *mangled;
01357 success = demangle_qualified (work, mangled, declp, 1, 0);
01358 if (success)
01359 remember_type (work, oldmangled, *mangled - oldmangled);
01360 if (AUTO_DEMANGLING || GNU_DEMANGLING)
01361 expect_func = 1;
01362 oldmangled = NULL;
01363 break;
01364
01365 case 'K':
01366 oldmangled = *mangled;
01367 success = demangle_qualified (work, mangled, declp, 1, 0);
01368 if (AUTO_DEMANGLING || GNU_DEMANGLING)
01369 {
01370 expect_func = 1;
01371 }
01372 oldmangled = NULL;
01373 break;
01374
01375 case 'S':
01376
01377 if (oldmangled == NULL)
01378 {
01379 oldmangled = *mangled;
01380 }
01381 (*mangled)++;
01382 work -> static_type = 1;
01383 break;
01384
01385 case 'C':
01386 case 'V':
01387 case 'u':
01388 work->type_quals |= code_for_qualifier (**mangled);
01389
01390
01391 if (oldmangled == NULL)
01392 oldmangled = *mangled;
01393 (*mangled)++;
01394 break;
01395
01396 case 'L':
01397
01398 if (HP_DEMANGLING)
01399 {
01400 while (**mangled && (**mangled != '_'))
01401 (*mangled)++;
01402 if (!**mangled)
01403 success = 0;
01404 else
01405 (*mangled)++;
01406 }
01407 else
01408 success = 0;
01409 break;
01410
01411 case '0': case '1': case '2': case '3': case '4':
01412 case '5': case '6': case '7': case '8': case '9':
01413 if (oldmangled == NULL)
01414 {
01415 oldmangled = *mangled;
01416 }
01417 work->temp_start = -1;
01418 success = demangle_class (work, mangled, declp);
01419 if (success)
01420 {
01421 remember_type (work, oldmangled, *mangled - oldmangled);
01422 }
01423 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
01424 {
01425
01426
01427 if (**mangled != 'F')
01428 expect_func = 1;
01429 }
01430 oldmangled = NULL;
01431 break;
01432
01433 case 'B':
01434 {
01435 string s;
01436 success = do_type (work, mangled, &s);
01437 if (success)
01438 {
01439 string_append (&s, SCOPE_STRING (work));
01440 string_prepends (declp, &s);
01441 string_delete (&s);
01442 }
01443 oldmangled = NULL;
01444 expect_func = 1;
01445 }
01446 break;
01447
01448 case 'F':
01449
01450
01451
01452
01453
01454
01455 oldmangled = NULL;
01456 func_done = 1;
01457 (*mangled)++;
01458
01459
01460
01461
01462
01463
01464 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
01465 {
01466 forget_types (work);
01467 }
01468 success = demangle_args (work, mangled, declp);
01469
01470
01471
01472 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
01473 {
01474 ++(*mangled);
01475
01476 success = do_type (work, mangled, &tname);
01477 string_delete (&tname);
01478 }
01479
01480 break;
01481
01482 case 't':
01483
01484 string_init(&trawname);
01485 string_init(&tname);
01486 if (oldmangled == NULL)
01487 {
01488 oldmangled = *mangled;
01489 }
01490 success = demangle_template (work, mangled, &tname,
01491 &trawname, 1, 1);
01492 if (success)
01493 {
01494 remember_type (work, oldmangled, *mangled - oldmangled);
01495 }
01496 string_append (&tname, SCOPE_STRING (work));
01497
01498 string_prepends(declp, &tname);
01499 if (work -> destructor & 1)
01500 {
01501 string_prepend (&trawname, "~");
01502 string_appends (declp, &trawname);
01503 work->destructor -= 1;
01504 }
01505 if ((work->constructor & 1) || (work->destructor & 1))
01506 {
01507 string_appends (declp, &trawname);
01508 work->constructor -= 1;
01509 }
01510 string_delete(&trawname);
01511 string_delete(&tname);
01512 oldmangled = NULL;
01513 expect_func = 1;
01514 break;
01515
01516 case '_':
01517 if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
01518 {
01519
01520 string return_type;
01521
01522 (*mangled)++;
01523 success = do_type (work, mangled, &return_type);
01524 APPEND_BLANK (&return_type);
01525
01526 string_prepends (declp, &return_type);
01527 string_delete (&return_type);
01528 break;
01529 }
01530 else
01531
01532
01533
01534
01535
01536
01537
01538
01539 if (HP_DEMANGLING)
01540 {
01541 (*mangled)++;
01542 while (**mangled && ISDIGIT ((unsigned char)**mangled))
01543 (*mangled)++;
01544 }
01545 else
01546 success = 0;
01547 break;
01548
01549 case 'H':
01550 if (AUTO_DEMANGLING || GNU_DEMANGLING)
01551 {
01552
01553 success = demangle_template (work, mangled, declp, 0, 0,
01554 0);
01555 if (!(work->constructor & 1))
01556 expect_return_type = 1;
01557 (*mangled)++;
01558 break;
01559 }
01560 else
01561
01562 {;}
01563
01564 default:
01565 if (AUTO_DEMANGLING || GNU_DEMANGLING)
01566 {
01567
01568
01569 func_done = 1;
01570 success = demangle_args (work, mangled, declp);
01571 }
01572 else
01573 {
01574
01575
01576
01577
01578 success = 0;
01579 }
01580 break;
01581 }
01582
01583
01584
01585 {
01586 if (success && expect_func)
01587 {
01588 func_done = 1;
01589 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
01590 {
01591 forget_types (work);
01592 }
01593 success = demangle_args (work, mangled, declp);
01594
01595
01596
01597 expect_func = 0;
01598 }
01599 }
01600 }
01601 if (success && !func_done)
01602 {
01603 if (AUTO_DEMANGLING || GNU_DEMANGLING)
01604 {
01605
01606
01607
01608
01609
01610
01611 success = demangle_args (work, mangled, declp);
01612 }
01613 }
01614 if (success && PRINT_ARG_TYPES)
01615 {
01616 if (work->static_type)
01617 string_append (declp, " static");
01618 if (work->type_quals != TYPE_UNQUALIFIED)
01619 {
01620 APPEND_BLANK (declp);
01621 string_append (declp, qualifier_string (work->type_quals));
01622 }
01623 }
01624
01625 return (success);
01626 }
01627
01628 #if 0
01629
01630 static int
01631 demangle_method_args (work, mangled, declp)
01632 struct work_stuff *work;
01633 const char **mangled;
01634 string *declp;
01635 {
01636 int success = 0;
01637
01638 if (work -> static_type)
01639 {
01640 string_append (declp, *mangled + 1);
01641 *mangled += strlen (*mangled);
01642 success = 1;
01643 }
01644 else
01645 {
01646 success = demangle_args (work, mangled, declp);
01647 }
01648 return (success);
01649 }
01650
01651 #endif
01652
01653 static int
01654 demangle_template_template_parm (work, mangled, tname)
01655 struct work_stuff *work;
01656 const char **mangled;
01657 string *tname;
01658 {
01659 int i;
01660 int r;
01661 int need_comma = 0;
01662 int success = 1;
01663 string temp;
01664
01665 string_append (tname, "template <");
01666
01667 if (get_count (mangled, &r))
01668 {
01669 for (i = 0; i < r; i++)
01670 {
01671 if (need_comma)
01672 {
01673 string_append (tname, ", ");
01674 }
01675
01676
01677 if (**mangled == 'Z')
01678 {
01679 (*mangled)++;
01680 string_append (tname, "class");
01681 }
01682
01683 else if (**mangled == 'z')
01684 {
01685 (*mangled)++;
01686 success =
01687 demangle_template_template_parm (work, mangled, tname);
01688 if (!success)
01689 {
01690 break;
01691 }
01692 }
01693 else
01694 {
01695
01696 success = do_type (work, mangled, &temp);
01697 if (success)
01698 {
01699 string_appends (tname, &temp);
01700 }
01701 string_delete(&temp);
01702 if (!success)
01703 {
01704 break;
01705 }
01706 }
01707 need_comma = 1;
01708 }
01709
01710 }
01711 if (tname->p[-1] == '>')
01712 string_append (tname, " ");
01713 string_append (tname, "> class");
01714 return (success);
01715 }
01716
01717 static int
01718 demangle_expression (work, mangled, s, tk)
01719 struct work_stuff *work;
01720 const char** mangled;
01721 string* s;
01722 type_kind_t tk;
01723 {
01724 int need_operator = 0;
01725 int success;
01726
01727 success = 1;
01728 string_appendn (s, "(", 1);
01729 (*mangled)++;
01730 while (success && **mangled != 'W' && **mangled != '\0')
01731 {
01732 if (need_operator)
01733 {
01734 size_t i;
01735 size_t len;
01736
01737 success = 0;
01738
01739 len = strlen (*mangled);
01740
01741 for (i = 0; i < ARRAY_SIZE (optable); ++i)
01742 {
01743 size_t l = strlen (optable[i].in);
01744
01745 if (l <= len
01746 && memcmp (optable[i].in, *mangled, l) == 0)
01747 {
01748 string_appendn (s, " ", 1);
01749 string_append (s, optable[i].out);
01750 string_appendn (s, " ", 1);
01751 success = 1;
01752 (*mangled) += l;
01753 break;
01754 }
01755 }
01756
01757 if (!success)
01758 break;
01759 }
01760 else
01761 need_operator = 1;
01762
01763 success = demangle_template_value_parm (work, mangled, s, tk);
01764 }
01765
01766 if (**mangled != 'W')
01767 success = 0;
01768 else
01769 {
01770 string_appendn (s, ")", 1);
01771 (*mangled)++;
01772 }
01773
01774 return success;
01775 }
01776
01777 static int
01778 demangle_integral_value (work, mangled, s)
01779 struct work_stuff *work;
01780 const char** mangled;
01781 string* s;
01782 {
01783 int success;
01784
01785 if (**mangled == 'E')
01786 success = demangle_expression (work, mangled, s, tk_integral);
01787 else if (**mangled == 'Q' || **mangled == 'K')
01788 success = demangle_qualified (work, mangled, s, 0, 1);
01789 else
01790 {
01791 int value;
01792
01793
01794
01795 int multidigit_without_leading_underscore = 0;
01796 int leave_following_underscore = 0;
01797
01798 success = 0;
01799
01800 if (**mangled == '_')
01801 {
01802 if (mangled[0][1] == 'm')
01803 {
01804
01805
01806
01807
01808 multidigit_without_leading_underscore = 1;
01809 string_appendn (s, "-", 1);
01810 (*mangled) += 2;
01811 }
01812 else
01813 {
01814
01815
01816
01817 leave_following_underscore = 1;
01818 }
01819 }
01820 else
01821 {
01822
01823 if (**mangled == 'm')
01824 {
01825 string_appendn (s, "-", 1);
01826 (*mangled)++;
01827 }
01828
01829
01830
01831
01832 multidigit_without_leading_underscore = 1;
01833
01834
01835 leave_following_underscore = 1;
01836 }
01837
01838
01839
01840
01841
01842 if (multidigit_without_leading_underscore)
01843 value = consume_count (mangled);
01844 else
01845 value = consume_count_with_underscores (mangled);
01846
01847 if (value != -1)
01848 {
01849 char buf[INTBUF_SIZE];
01850 sprintf (buf, "%d", value);
01851 string_append (s, buf);
01852
01853
01854
01855
01856
01857
01858
01859
01860 if ((value > 9 || multidigit_without_leading_underscore)
01861 && ! leave_following_underscore
01862 && **mangled == '_')
01863 (*mangled)++;
01864
01865
01866 success = 1;
01867 }
01868 }
01869
01870 return success;
01871 }
01872
01873
01874
01875 static int
01876 demangle_real_value (work, mangled, s)
01877 struct work_stuff *work;
01878 const char **mangled;
01879 string* s;
01880 {
01881 if (**mangled == 'E')
01882 return demangle_expression (work, mangled, s, tk_real);
01883
01884 if (**mangled == 'm')
01885 {
01886 string_appendn (s, "-", 1);
01887 (*mangled)++;
01888 }
01889 while (ISDIGIT ((unsigned char)**mangled))
01890 {
01891 string_appendn (s, *mangled, 1);
01892 (*mangled)++;
01893 }
01894 if (**mangled == '.')
01895 {
01896 string_appendn (s, ".", 1);
01897 (*mangled)++;
01898 while (ISDIGIT ((unsigned char)**mangled))
01899 {
01900 string_appendn (s, *mangled, 1);
01901 (*mangled)++;
01902 }
01903 }
01904 if (**mangled == 'e')
01905 {
01906 string_appendn (s, "e", 1);
01907 (*mangled)++;
01908 while (ISDIGIT ((unsigned char)**mangled))
01909 {
01910 string_appendn (s, *mangled, 1);
01911 (*mangled)++;
01912 }
01913 }
01914
01915 return 1;
01916 }
01917
01918 static int
01919 demangle_template_value_parm (work, mangled, s, tk)
01920 struct work_stuff *work;
01921 const char **mangled;
01922 string* s;
01923 type_kind_t tk;
01924 {
01925 int success = 1;
01926
01927 if (**mangled == 'Y')
01928 {
01929
01930 int idx;
01931
01932 (*mangled)++;
01933 idx = consume_count_with_underscores (mangled);
01934 if (idx == -1
01935 || (work->tmpl_argvec && idx >= work->ntmpl_args)
01936 || consume_count_with_underscores (mangled) == -1)
01937 return -1;
01938 if (work->tmpl_argvec)
01939 string_append (s, work->tmpl_argvec[idx]);
01940 else
01941 string_append_template_idx (s, idx);
01942 }
01943 else if (tk == tk_integral)
01944 success = demangle_integral_value (work, mangled, s);
01945 else if (tk == tk_char)
01946 {
01947 char tmp[2];
01948 int val;
01949 if (**mangled == 'm')
01950 {
01951 string_appendn (s, "-", 1);
01952 (*mangled)++;
01953 }
01954 string_appendn (s, "'", 1);
01955 val = consume_count(mangled);
01956 if (val <= 0)
01957 success = 0;
01958 else
01959 {
01960 tmp[0] = (char)val;
01961 tmp[1] = '\0';
01962 string_appendn (s, &tmp[0], 1);
01963 string_appendn (s, "'", 1);
01964 }
01965 }
01966 else if (tk == tk_bool)
01967 {
01968 int val = consume_count (mangled);
01969 if (val == 0)
01970 string_appendn (s, "false", 5);
01971 else if (val == 1)
01972 string_appendn (s, "true", 4);
01973 else
01974 success = 0;
01975 }
01976 else if (tk == tk_real)
01977 success = demangle_real_value (work, mangled, s);
01978 else if (tk == tk_pointer || tk == tk_reference)
01979 {
01980 if (**mangled == 'Q')
01981 success = demangle_qualified (work, mangled, s,
01982 0,
01983 1);
01984 else
01985 {
01986 int symbol_len = consume_count (mangled);
01987 if (symbol_len == -1)
01988 return -1;
01989 if (symbol_len == 0)
01990 string_appendn (s, "0", 1);
01991 else
01992 {
01993 char *p = xmalloc (symbol_len + 1), *q;
01994 strncpy (p, *mangled, symbol_len);
01995 p [symbol_len] = '\0';
01996
01997
01998
01999
02000
02001 q = cplus_demangle (p, work->options);
02002 if (tk == tk_pointer)
02003 string_appendn (s, "&", 1);
02004
02005
02006 if (q)
02007 {
02008 string_append (s, q);
02009 free (q);
02010 }
02011 else
02012 string_append (s, p);
02013 free (p);
02014 }
02015 *mangled += symbol_len;
02016 }
02017 }
02018
02019 return success;
02020 }
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030 static int
02031 demangle_template (work, mangled, tname, trawname, is_type, remember)
02032 struct work_stuff *work;
02033 const char **mangled;
02034 string *tname;
02035 string *trawname;
02036 int is_type;
02037 int remember;
02038 {
02039 int i;
02040 int r;
02041 int need_comma = 0;
02042 int success = 0;
02043 int is_java_array = 0;
02044 string temp;
02045
02046 (*mangled)++;
02047 if (is_type)
02048 {
02049
02050 if (**mangled == 'z')
02051 {
02052 int idx;
02053 (*mangled)++;
02054 (*mangled)++;
02055
02056 idx = consume_count_with_underscores (mangled);
02057 if (idx == -1
02058 || (work->tmpl_argvec && idx >= work->ntmpl_args)
02059 || consume_count_with_underscores (mangled) == -1)
02060 return (0);
02061
02062 if (work->tmpl_argvec)
02063 {
02064 string_append (tname, work->tmpl_argvec[idx]);
02065 if (trawname)
02066 string_append (trawname, work->tmpl_argvec[idx]);
02067 }
02068 else
02069 {
02070 string_append_template_idx (tname, idx);
02071 if (trawname)
02072 string_append_template_idx (trawname, idx);
02073 }
02074 }
02075 else
02076 {
02077 if ((r = consume_count (mangled)) <= 0
02078 || (int) strlen (*mangled) < r)
02079 {
02080 return (0);
02081 }
02082 is_java_array = (work -> options & DMGL_JAVA)
02083 && strncmp (*mangled, "JArray1Z", 8) == 0;
02084 if (! is_java_array)
02085 {
02086 string_appendn (tname, *mangled, r);
02087 }
02088 if (trawname)
02089 string_appendn (trawname, *mangled, r);
02090 *mangled += r;
02091 }
02092 }
02093 if (!is_java_array)
02094 string_append (tname, "<");
02095
02096 if (!get_count (mangled, &r))
02097 {
02098 return (0);
02099 }
02100 if (!is_type)
02101 {
02102
02103 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
02104 work->ntmpl_args = r;
02105 for (i = 0; i < r; i++)
02106 work->tmpl_argvec[i] = 0;
02107 }
02108 for (i = 0; i < r; i++)
02109 {
02110 if (need_comma)
02111 {
02112 string_append (tname, ", ");
02113 }
02114
02115 if (**mangled == 'Z')
02116 {
02117 (*mangled)++;
02118
02119 success = do_type (work, mangled, &temp);
02120 if (success)
02121 {
02122 string_appends (tname, &temp);
02123
02124 if (!is_type)
02125 {
02126
02127 int len = temp.p - temp.b;
02128 work->tmpl_argvec[i] = xmalloc (len + 1);
02129 memcpy (work->tmpl_argvec[i], temp.b, len);
02130 work->tmpl_argvec[i][len] = '\0';
02131 }
02132 }
02133 string_delete(&temp);
02134 if (!success)
02135 {
02136 break;
02137 }
02138 }
02139
02140 else if (**mangled == 'z')
02141 {
02142 int r2;
02143 (*mangled)++;
02144 success = demangle_template_template_parm (work, mangled, tname);
02145
02146 if (success
02147 && (r2 = consume_count (mangled)) > 0
02148 && (int) strlen (*mangled) >= r2)
02149 {
02150 string_append (tname, " ");
02151 string_appendn (tname, *mangled, r2);
02152 if (!is_type)
02153 {
02154
02155 int len = r2;
02156 work->tmpl_argvec[i] = xmalloc (len + 1);
02157 memcpy (work->tmpl_argvec[i], *mangled, len);
02158 work->tmpl_argvec[i][len] = '\0';
02159 }
02160 *mangled += r2;
02161 }
02162 if (!success)
02163 {
02164 break;
02165 }
02166 }
02167 else
02168 {
02169 string param;
02170 string* s;
02171
02172
02173
02174
02175 success = do_type (work, mangled, &temp);
02176 string_delete(&temp);
02177 if (!success)
02178 break;
02179
02180 if (!is_type)
02181 {
02182 s = ¶m;
02183 string_init (s);
02184 }
02185 else
02186 s = tname;
02187
02188 success = demangle_template_value_parm (work, mangled, s,
02189 (type_kind_t) success);
02190
02191 if (!success)
02192 {
02193 if (!is_type)
02194 string_delete (s);
02195 success = 0;
02196 break;
02197 }
02198
02199 if (!is_type)
02200 {
02201 int len = s->p - s->b;
02202 work->tmpl_argvec[i] = xmalloc (len + 1);
02203 memcpy (work->tmpl_argvec[i], s->b, len);
02204 work->tmpl_argvec[i][len] = '\0';
02205
02206 string_appends (tname, s);
02207 string_delete (s);
02208 }
02209 }
02210 need_comma = 1;
02211 }
02212 if (is_java_array)
02213 {
02214 string_append (tname, "[]");
02215 }
02216 else
02217 {
02218 if (tname->p[-1] == '>')
02219 string_append (tname, " ");
02220 string_append (tname, ">");
02221 }
02222
02223 if (is_type && remember)
02224 {
02225 const int bindex = register_Btype (work);
02226 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
02227 }
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242 return (success);
02243 }
02244
02245 static int
02246 arm_pt (work, mangled, n, anchor, args)
02247 struct work_stuff *work;
02248 const char *mangled;
02249 int n;
02250 const char **anchor, **args;
02251 {
02252
02253
02254 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__")))
02255 {
02256 int len;
02257 *args = *anchor + 6;
02258 len = consume_count (args);
02259 if (len == -1)
02260 return 0;
02261 if (*args + len == mangled + n && **args == '_')
02262 {
02263 ++*args;
02264 return 1;
02265 }
02266 }
02267 if (AUTO_DEMANGLING || EDG_DEMANGLING)
02268 {
02269 if ((*anchor = strstr (mangled, "__tm__"))
02270 || (*anchor = strstr (mangled, "__ps__"))
02271 || (*anchor = strstr (mangled, "__pt__")))
02272 {
02273 int len;
02274 *args = *anchor + 6;
02275 len = consume_count (args);
02276 if (len == -1)
02277 return 0;
02278 if (*args + len == mangled + n && **args == '_')
02279 {
02280 ++*args;
02281 return 1;
02282 }
02283 }
02284 else if ((*anchor = strstr (mangled, "__S")))
02285 {
02286 int len;
02287 *args = *anchor + 3;
02288 len = consume_count (args);
02289 if (len == -1)
02290 return 0;
02291 if (*args + len == mangled + n && **args == '_')
02292 {
02293 ++*args;
02294 return 1;
02295 }
02296 }
02297 }
02298
02299 return 0;
02300 }
02301
02302 static void
02303 demangle_arm_hp_template (work, mangled, n, declp)
02304 struct work_stuff *work;
02305 const char **mangled;
02306 int n;
02307 string *declp;
02308 {
02309 const char *p;
02310 const char *args;
02311 const char *e = *mangled + n;
02312 string arg;
02313
02314
02315
02316 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
02317 {
02318 char *start_spec_args = NULL;
02319 int hold_options;
02320
02321
02322
02323 start_spec_args = strchr (*mangled, '<');
02324 if (start_spec_args && (start_spec_args - *mangled < n))
02325 string_appendn (declp, *mangled, start_spec_args - *mangled);
02326 else
02327 string_appendn (declp, *mangled, n);
02328 (*mangled) += n + 1;
02329 string_init (&arg);
02330 if (work->temp_start == -1)
02331 work->temp_start = declp->p - declp->b;
02332
02333
02334
02335 hold_options = work->options;
02336 work->options |= DMGL_PARAMS;
02337
02338 string_append (declp, "<");
02339 while (1)
02340 {
02341 string_delete (&arg);
02342 switch (**mangled)
02343 {
02344 case 'T':
02345
02346 (*mangled)++;
02347 if (!do_type (work, mangled, &arg))
02348 goto hpacc_template_args_done;
02349 break;
02350
02351 case 'U':
02352 case 'S':
02353
02354 if (!do_hpacc_template_const_value (work, mangled, &arg))
02355 goto hpacc_template_args_done;
02356 break;
02357
02358 case 'A':
02359
02360 if (!do_hpacc_template_literal (work, mangled, &arg))
02361 goto hpacc_template_args_done;
02362 break;
02363
02364 default:
02365
02366
02367
02368 goto hpacc_template_args_done;
02369 }
02370 string_appends (declp, &arg);
02371
02372
02373
02374 if ((**mangled == '\000') || (**mangled == '_'))
02375 break;
02376 else
02377 string_append (declp, ",");
02378 }
02379 hpacc_template_args_done:
02380 string_append (declp, ">");
02381 string_delete (&arg);
02382 if (**mangled == '_')
02383 (*mangled)++;
02384 work->options = hold_options;
02385 return;
02386 }
02387
02388 else if (arm_pt (work, *mangled, n, &p, &args))
02389 {
02390 int hold_options;
02391 string type_str;
02392
02393 string_init (&arg);
02394 string_appendn (declp, *mangled, p - *mangled);
02395 if (work->temp_start == -1)
02396 work->temp_start = declp->p - declp->b;
02397
02398
02399
02400 hold_options = work->options;
02401 work->options |= DMGL_PARAMS;
02402
02403 string_append (declp, "<");
02404
02405 while (args < e) {
02406 string_delete (&arg);
02407
02408
02409 switch (*args)
02410 {
02411
02412
02413
02414 case 'X':
02415
02416 args++;
02417 if (!do_type (work, &args, &type_str))
02418 goto cfront_template_args_done;
02419 string_append (&arg, "(");
02420 string_appends (&arg, &type_str);
02421 string_delete (&type_str);
02422 string_append (&arg, ")");
02423 if (*args != 'L')
02424 goto cfront_template_args_done;
02425 args++;
02426
02427 if (!snarf_numeric_literal (&args, &arg))
02428 goto cfront_template_args_done;
02429 break;
02430
02431 case 'L':
02432
02433 args++;
02434 if (!snarf_numeric_literal (&args, &arg))
02435 goto cfront_template_args_done;
02436 break;
02437 default:
02438
02439 {
02440 const char* old_args = args;
02441 if (!do_type (work, &args, &arg))
02442 goto cfront_template_args_done;
02443
02444
02445 if (args == old_args)
02446 {
02447 work->options = hold_options;
02448 return;
02449 }
02450 }
02451 }
02452 string_appends (declp, &arg);
02453 string_append (declp, ",");
02454 }
02455 cfront_template_args_done:
02456 string_delete (&arg);
02457 if (args >= e)
02458 --declp->p;
02459 string_append (declp, ">");
02460 work->options = hold_options;
02461 }
02462 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
02463 && (*mangled)[9] == 'N'
02464 && (*mangled)[8] == (*mangled)[10]
02465 && strchr (cplus_markers, (*mangled)[8]))
02466 {
02467
02468 string_append (declp, "{anonymous}");
02469 }
02470 else
02471 {
02472 if (work->temp_start == -1)
02473 work->temp_start = 0;
02474 string_appendn (declp, *mangled, n);
02475 }
02476 *mangled += n;
02477 }
02478
02479
02480
02481
02482
02483 static int
02484 demangle_class_name (work, mangled, declp)
02485 struct work_stuff *work;
02486 const char **mangled;
02487 string *declp;
02488 {
02489 int n;
02490 int success = 0;
02491
02492 n = consume_count (mangled);
02493 if (n == -1)
02494 return 0;
02495 if ((int) strlen (*mangled) >= n)
02496 {
02497 demangle_arm_hp_template (work, mangled, n, declp);
02498 success = 1;
02499 }
02500
02501 return (success);
02502 }
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539 static int
02540 demangle_class (work, mangled, declp)
02541 struct work_stuff *work;
02542 const char **mangled;
02543 string *declp;
02544 {
02545 int success = 0;
02546 int btype;
02547 string class_name;
02548 char *save_class_name_end = 0;
02549
02550 string_init (&class_name);
02551 btype = register_Btype (work);
02552 if (demangle_class_name (work, mangled, &class_name))
02553 {
02554 save_class_name_end = class_name.p;
02555 if ((work->constructor & 1) || (work->destructor & 1))
02556 {
02557
02558 if (work->temp_start && (work->temp_start != -1))
02559 {
02560 class_name.p = class_name.b + work->temp_start;
02561 }
02562 string_prepends (declp, &class_name);
02563 if (work -> destructor & 1)
02564 {
02565 string_prepend (declp, "~");
02566 work -> destructor -= 1;
02567 }
02568 else
02569 {
02570 work -> constructor -= 1;
02571 }
02572 }
02573 class_name.p = save_class_name_end;
02574 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
02575 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
02576 string_prepend (declp, SCOPE_STRING (work));
02577 string_prepends (declp, &class_name);
02578 success = 1;
02579 }
02580 string_delete (&class_name);
02581 return (success);
02582 }
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594 static int
02595 iterate_demangle_function (work, mangled, declp, scan)
02596 struct work_stuff *work;
02597 const char **mangled;
02598 string *declp;
02599 const char *scan;
02600 {
02601 const char *mangle_init = *mangled;
02602 int success = 0;
02603 string decl_init;
02604 struct work_stuff work_init;
02605
02606 if (*(scan + 2) == '\0')
02607 return 0;
02608
02609
02610
02611 if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING
02612 || strstr (scan + 2, "__") == NULL)
02613 {
02614 demangle_function_name (work, mangled, declp, scan);
02615 return 1;
02616 }
02617
02618
02619
02620 string_init (&decl_init);
02621 string_appends (&decl_init, declp);
02622 memset (&work_init, 0, sizeof work_init);
02623 work_stuff_copy_to_from (&work_init, work);
02624
02625
02626
02627
02628
02629
02630
02631 while (scan[2])
02632 {
02633 demangle_function_name (work, mangled, declp, scan);
02634 success = demangle_signature (work, mangled, declp);
02635 if (success)
02636 break;
02637
02638
02639 *mangled = mangle_init;
02640 string_clear (declp);
02641 string_appends (declp, &decl_init);
02642 work_stuff_copy_to_from (work, &work_init);
02643
02644
02645 scan += 2;
02646
02647
02648 while (*scan && (scan[0] != '_' || scan[1] != '_'))
02649 scan++;
02650
02651
02652 while (*scan && *scan == '_')
02653 scan++;
02654 scan -= 2;
02655 }
02656
02657
02658 delete_work_stuff (&work_init);
02659 string_delete (&decl_init);
02660
02661 return success;
02662 }
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697 static int
02698 demangle_prefix (work, mangled, declp)
02699 struct work_stuff *work;
02700 const char **mangled;
02701 string *declp;
02702 {
02703 int success = 1;
02704 const char *scan;
02705 int i;
02706
02707 if (strlen(*mangled) > 6
02708 && (strncmp(*mangled, "_imp__", 6) == 0
02709 || strncmp(*mangled, "__imp_", 6) == 0))
02710 {
02711
02712
02713
02714 (*mangled) += 6;
02715 work->dllimported = 1;
02716 }
02717 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
02718 {
02719 char *marker = strchr (cplus_markers, (*mangled)[8]);
02720 if (marker != NULL && *marker == (*mangled)[10])
02721 {
02722 if ((*mangled)[9] == 'D')
02723 {
02724
02725 (*mangled) += 11;
02726 work->destructor = 2;
02727 if (gnu_special (work, mangled, declp))
02728 return success;
02729 }
02730 else if ((*mangled)[9] == 'I')
02731 {
02732
02733 (*mangled) += 11;
02734 work->constructor = 2;
02735 if (gnu_special (work, mangled, declp))
02736 return success;
02737 }
02738 }
02739 }
02740 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
02741 {
02742
02743 (*mangled) += 7;
02744 work->destructor = 2;
02745 }
02746 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
02747 {
02748
02749 (*mangled) += 7;
02750 work->constructor = 2;
02751 }
02752
02753
02754
02755
02756
02757 {
02758 scan = *mangled;
02759
02760 do {
02761 scan = strchr (scan, '_');
02762 } while (scan != NULL && *++scan != '_');
02763
02764 if (scan != NULL) --scan;
02765 }
02766
02767 if (scan != NULL)
02768 {
02769
02770
02771 i = strspn (scan, "_");
02772 if (i > 2)
02773 {
02774 scan += (i - 2);
02775 }
02776 }
02777
02778 if (scan == NULL)
02779 {
02780 success = 0;
02781 }
02782 else if (work -> static_type)
02783 {
02784 if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
02785 {
02786 success = 0;
02787 }
02788 }
02789 else if ((scan == *mangled)
02790 && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
02791 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
02792 {
02793
02794
02795
02796 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
02797 && ISDIGIT ((unsigned char)scan[2]))
02798 {
02799 *mangled = scan + 2;
02800 consume_count (mangled);
02801 string_append (declp, *mangled);
02802 *mangled += strlen (*mangled);
02803 success = 1;
02804 }
02805 else
02806 {
02807
02808
02809
02810
02811 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
02812 work -> constructor += 1;
02813 *mangled = scan + 2;
02814 }
02815 }
02816 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
02817 {
02818
02819 success = 1;
02820
02821
02822 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
02823 }
02824 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
02825 || (scan[2] == 'p' && scan[3] == 's')
02826 || (scan[2] == 'p' && scan[3] == 't')))
02827 {
02828
02829 success = 1;
02830
02831
02832 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
02833 }
02834 else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
02835 && (scan[2] != 't'))
02836 {
02837
02838
02839
02840 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
02841 || (arm_special (mangled, declp) == 0))
02842 {
02843 while (*scan == '_')
02844 {
02845 scan++;
02846 }
02847 if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
02848 {
02849
02850
02851 success = 0;
02852 }
02853 else
02854 return iterate_demangle_function (work, mangled, declp, scan);
02855 }
02856 }
02857 else if (*(scan + 2) != '\0')
02858 {
02859
02860
02861
02862
02863 return iterate_demangle_function (work, mangled, declp, scan);
02864 }
02865 else
02866 {
02867
02868 success = 0;
02869 }
02870
02871 if (!success && (work->constructor == 2 || work->destructor == 2))
02872 {
02873 string_append (declp, *mangled);
02874 *mangled += strlen (*mangled);
02875 success = 1;
02876 }
02877 return (success);
02878 }
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908 static int
02909 gnu_special (work, mangled, declp)
02910 struct work_stuff *work;
02911 const char **mangled;
02912 string *declp;
02913 {
02914 int n;
02915 int success = 1;
02916 const char *p;
02917
02918 if ((*mangled)[0] == '_'
02919 && strchr (cplus_markers, (*mangled)[1]) != NULL
02920 && (*mangled)[2] == '_')
02921 {
02922
02923 (*mangled) += 3;
02924 work -> destructor += 1;
02925 }
02926 else if ((*mangled)[0] == '_'
02927 && (((*mangled)[1] == '_'
02928 && (*mangled)[2] == 'v'
02929 && (*mangled)[3] == 't'
02930 && (*mangled)[4] == '_')
02931 || ((*mangled)[1] == 'v'
02932 && (*mangled)[2] == 't'
02933 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
02934 {
02935
02936
02937
02938
02939 if ((*mangled)[2] == 'v')
02940 (*mangled) += 5;
02941 else
02942 (*mangled) += 4;
02943 while (**mangled != '\0')
02944 {
02945 switch (**mangled)
02946 {
02947 case 'Q':
02948 case 'K':
02949 success = demangle_qualified (work, mangled, declp, 0, 1);
02950 break;
02951 case 't':
02952 success = demangle_template (work, mangled, declp, 0, 1,
02953 1);
02954 break;
02955 default:
02956 if (ISDIGIT((unsigned char)*mangled[0]))
02957 {
02958 n = consume_count(mangled);
02959
02960
02961
02962
02963 if (n > (int) strlen (*mangled))
02964 {
02965 success = 1;
02966 break;
02967 }
02968 }
02969 else
02970 {
02971 n = strcspn (*mangled, cplus_markers);
02972 }
02973 string_appendn (declp, *mangled, n);
02974 (*mangled) += n;
02975 }
02976
02977 p = strpbrk (*mangled, cplus_markers);
02978 if (success && ((p == NULL) || (p == *mangled)))
02979 {
02980 if (p != NULL)
02981 {
02982 string_append (declp, SCOPE_STRING (work));
02983 (*mangled)++;
02984 }
02985 }
02986 else
02987 {
02988 success = 0;
02989 break;
02990 }
02991 }
02992 if (success)
02993 string_append (declp, " virtual table");
02994 }
02995 else if ((*mangled)[0] == '_'
02996 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
02997 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
02998 {
02999
03000 (*mangled)++;
03001 switch (**mangled)
03002 {
03003 case 'Q':
03004 case 'K':
03005 success = demangle_qualified (work, mangled, declp, 0, 1);
03006 break;
03007 case 't':
03008 success = demangle_template (work, mangled, declp, 0, 1, 1);
03009 break;
03010 default:
03011 n = consume_count (mangled);
03012 if (n < 0 || n > (long) strlen (*mangled))
03013 {
03014 success = 0;
03015 break;
03016 }
03017
03018 if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
03019 && (*mangled)[9] == 'N'
03020 && (*mangled)[8] == (*mangled)[10]
03021 && strchr (cplus_markers, (*mangled)[8]))
03022 {
03023
03024
03025
03026
03027 string_append (declp, "{anonymous}");
03028 (*mangled) += n;
03029
03030
03031
03032 p = strpbrk (*mangled, cplus_markers);
03033 break;
03034 }
03035
03036 string_appendn (declp, *mangled, n);
03037 (*mangled) += n;
03038 }
03039 if (success && (p == *mangled))
03040 {
03041
03042
03043 (*mangled)++;
03044 string_append (declp, SCOPE_STRING (work));
03045 n = strlen (*mangled);
03046 string_appendn (declp, *mangled, n);
03047 (*mangled) += n;
03048 }
03049 else
03050 {
03051 success = 0;
03052 }
03053 }
03054 else if (strncmp (*mangled, "__thunk_", 8) == 0)
03055 {
03056 int delta;
03057
03058 (*mangled) += 8;
03059 delta = consume_count (mangled);
03060 if (delta == -1)
03061 success = 0;
03062 else
03063 {
03064 char *method = internal_cplus_demangle (work, ++*mangled);
03065
03066 if (method)
03067 {
03068 char buf[50];
03069 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
03070 string_append (declp, buf);
03071 string_append (declp, method);
03072 free (method);
03073 n = strlen (*mangled);
03074 (*mangled) += n;
03075 }
03076 else
03077 {
03078 success = 0;
03079 }
03080 }
03081 }
03082 else if (strncmp (*mangled, "__t", 3) == 0
03083 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
03084 {
03085 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
03086 (*mangled) += 4;
03087 switch (**mangled)
03088 {
03089 case 'Q':
03090 case 'K':
03091 success = demangle_qualified (work, mangled, declp, 0, 1);
03092 break;
03093 case 't':
03094 success = demangle_template (work, mangled, declp, 0, 1, 1);
03095 break;
03096 default:
03097 success = do_type (work, mangled, declp);
03098 break;
03099 }
03100 if (success && **mangled != '\0')
03101 success = 0;
03102 if (success)
03103 string_append (declp, p);
03104 }
03105 else
03106 {
03107 success = 0;
03108 }
03109 return (success);
03110 }
03111
03112 static void
03113 recursively_demangle(work, mangled, result, namelength)
03114 struct work_stuff *work;
03115 const char **mangled;
03116 string *result;
03117 int namelength;
03118 {
03119 char * recurse = (char *)NULL;
03120 char * recurse_dem = (char *)NULL;
03121
03122 recurse = (char *) xmalloc (namelength + 1);
03123 memcpy (recurse, *mangled, namelength);
03124 recurse[namelength] = '\000';
03125
03126 recurse_dem = cplus_demangle (recurse, work->options);
03127
03128 if (recurse_dem)
03129 {
03130 string_append (result, recurse_dem);
03131 free (recurse_dem);
03132 }
03133 else
03134 {
03135 string_appendn (result, *mangled, namelength);
03136 }
03137 free (recurse);
03138 *mangled += namelength;
03139 }
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164 static int
03165 arm_special (mangled, declp)
03166 const char **mangled;
03167 string *declp;
03168 {
03169 int n;
03170 int success = 1;
03171 const char *scan;
03172
03173 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
03174 {
03175
03176
03177
03178
03179 scan = *mangled + ARM_VTABLE_STRLEN;
03180 while (*scan != '\0')
03181 {
03182 n = consume_count (&scan);
03183 if (n == -1)
03184 {
03185 return (0);
03186 }
03187 scan += n;
03188 if (scan[0] == '_' && scan[1] == '_')
03189 {
03190 scan += 2;
03191 }
03192 }
03193 (*mangled) += ARM_VTABLE_STRLEN;
03194 while (**mangled != '\0')
03195 {
03196 n = consume_count (mangled);
03197 if (n == -1
03198 || n > (long) strlen (*mangled))
03199 return 0;
03200 string_prependn (declp, *mangled, n);
03201 (*mangled) += n;
03202 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
03203 {
03204 string_prepend (declp, "::");
03205 (*mangled) += 2;
03206 }
03207 }
03208 string_append (declp, " virtual table");
03209 }
03210 else
03211 {
03212 success = 0;
03213 }
03214 return (success);
03215 }
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249 static int
03250 demangle_qualified (work, mangled, result, isfuncname, append)
03251 struct work_stuff *work;
03252 const char **mangled;
03253 string *result;
03254 int isfuncname;
03255 int append;
03256 {
03257 int qualifiers = 0;
03258 int success = 1;
03259 char num[2];
03260 string temp;
03261 string last_name;
03262 int bindex = register_Btype (work);
03263
03264
03265
03266 isfuncname = (isfuncname
03267 && ((work->constructor & 1) || (work->destructor & 1)));
03268
03269 string_init (&temp);
03270 string_init (&last_name);
03271
03272 if ((*mangled)[0] == 'K')
03273 {
03274
03275 int idx;
03276 (*mangled)++;
03277 idx = consume_count_with_underscores (mangled);
03278 if (idx == -1 || idx >= work -> numk)
03279 success = 0;
03280 else
03281 string_append (&temp, work -> ktypevec[idx]);
03282 }
03283 else
03284 switch ((*mangled)[1])
03285 {
03286 case '_':
03287
03288
03289
03290 (*mangled)++;
03291 qualifiers = consume_count_with_underscores (mangled);
03292 if (qualifiers == -1)
03293 success = 0;
03294 break;
03295
03296 case '1':
03297 case '2':
03298 case '3':
03299 case '4':
03300 case '5':
03301 case '6':
03302 case '7':
03303 case '8':
03304 case '9':
03305
03306 num[0] = (*mangled)[1];
03307 num[1] = '\0';
03308 qualifiers = atoi (num);
03309
03310
03311
03312
03313 if ((*mangled)[2] == '_')
03314 {
03315 (*mangled)++;
03316 }
03317 (*mangled) += 2;
03318 break;
03319
03320 case '0':
03321 default:
03322 success = 0;
03323 }
03324
03325 if (!success)
03326 return success;
03327
03328
03329
03330
03331 while (qualifiers-- > 0)
03332 {
03333 int remember_K = 1;
03334 string_clear (&last_name);
03335
03336 if (*mangled[0] == '_')
03337 (*mangled)++;
03338
03339 if (*mangled[0] == 't')
03340 {
03341
03342
03343
03344
03345
03346
03347 success = demangle_template(work, mangled, &temp,
03348 &last_name, 1, 0);
03349 if (!success)
03350 break;
03351 }
03352 else if (*mangled[0] == 'K')
03353 {
03354 int idx;
03355 (*mangled)++;
03356 idx = consume_count_with_underscores (mangled);
03357 if (idx == -1 || idx >= work->numk)
03358 success = 0;
03359 else
03360 string_append (&temp, work->ktypevec[idx]);
03361 remember_K = 0;
03362
03363 if (!success) break;
03364 }
03365 else
03366 {
03367 if (EDG_DEMANGLING)
03368 {
03369 int namelength;
03370
03371
03372
03373 namelength = consume_count (mangled);
03374 if (namelength == -1)
03375 {
03376 success = 0;
03377 break;
03378 }
03379 recursively_demangle(work, mangled, &temp, namelength);
03380 }
03381 else
03382 {
03383 string_delete (&last_name);
03384 success = do_type (work, mangled, &last_name);
03385 if (!success)
03386 break;
03387 string_appends (&temp, &last_name);
03388 }
03389 }
03390
03391 if (remember_K)
03392 remember_Ktype (work, temp.b, LEN_STRING (&temp));
03393
03394 if (qualifiers > 0)
03395 string_append (&temp, SCOPE_STRING (work));
03396 }
03397
03398 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
03399
03400
03401
03402
03403
03404
03405 if (isfuncname)
03406 {
03407 string_append (&temp, SCOPE_STRING (work));
03408 if (work -> destructor & 1)
03409 string_append (&temp, "~");
03410 string_appends (&temp, &last_name);
03411 }
03412
03413
03414
03415
03416 if (append)
03417 string_appends (result, &temp);
03418 else
03419 {
03420 if (!STRING_EMPTY (result))
03421 string_append (&temp, SCOPE_STRING (work));
03422 string_prepends (result, &temp);
03423 }
03424
03425 string_delete (&last_name);
03426 string_delete (&temp);
03427 return (success);
03428 }
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476 static int
03477 get_count (type, count)
03478 const char **type;
03479 int *count;
03480 {
03481 const char *p;
03482 int n;
03483
03484 if (!ISDIGIT ((unsigned char)**type))
03485 return (0);
03486 else
03487 {
03488 *count = **type - '0';
03489 (*type)++;
03490 if (ISDIGIT ((unsigned char)**type))
03491 {
03492 p = *type;
03493 n = *count;
03494 do
03495 {
03496 n *= 10;
03497 n += *p - '0';
03498 p++;
03499 }
03500 while (ISDIGIT ((unsigned char)*p));
03501 if (*p == '_')
03502 {
03503 *type = p + 1;
03504 *count = n;
03505 }
03506 }
03507 }
03508 return (1);
03509 }
03510
03511
03512
03513
03514 static int
03515 do_type (work, mangled, result)
03516 struct work_stuff *work;
03517 const char **mangled;
03518 string *result;
03519 {
03520 int n;
03521 int done;
03522 int success;
03523 string decl;
03524 const char *remembered_type;
03525 int type_quals;
03526 type_kind_t tk = tk_none;
03527
03528 string_init (&decl);
03529 string_init (result);
03530
03531 done = 0;
03532 success = 1;
03533 while (success && !done)
03534 {
03535 int member;
03536 switch (**mangled)
03537 {
03538
03539
03540 case 'P':
03541 case 'p':
03542 (*mangled)++;
03543 if (! (work -> options & DMGL_JAVA))
03544 string_prepend (&decl, "*");
03545 if (tk == tk_none)
03546 tk = tk_pointer;
03547 break;
03548
03549
03550 case 'R':
03551 (*mangled)++;
03552 string_prepend (&decl, "&");
03553 if (tk == tk_none)
03554 tk = tk_reference;
03555 break;
03556
03557
03558 case 'A':
03559 {
03560 ++(*mangled);
03561 if (!STRING_EMPTY (&decl)
03562 && (decl.b[0] == '*' || decl.b[0] == '&'))
03563 {
03564 string_prepend (&decl, "(");
03565 string_append (&decl, ")");
03566 }
03567 string_append (&decl, "[");
03568 if (**mangled != '_')
03569 success = demangle_template_value_parm (work, mangled, &decl,
03570 tk_integral);
03571 if (**mangled == '_')
03572 ++(*mangled);
03573 string_append (&decl, "]");
03574 break;
03575 }
03576
03577
03578 case 'T':
03579 (*mangled)++;
03580 if (!get_count (mangled, &n) || n >= work -> ntypes)
03581 {
03582 success = 0;
03583 }
03584 else
03585 {
03586 remembered_type = work -> typevec[n];
03587 mangled = &remembered_type;
03588 }
03589 break;
03590
03591
03592 case 'F':
03593 (*mangled)++;
03594 if (!STRING_EMPTY (&decl)
03595 && (decl.b[0] == '*' || decl.b[0] == '&'))
03596 {
03597 string_prepend (&decl, "(");
03598 string_append (&decl, ")");
03599 }
03600
03601
03602
03603 if (!demangle_nested_args (work, mangled, &decl)
03604 || (**mangled != '_' && **mangled != '\0'))
03605 {
03606 success = 0;
03607 break;
03608 }
03609 if (success && (**mangled == '_'))
03610 (*mangled)++;
03611 break;
03612
03613 case 'M':
03614 case 'O':
03615 {
03616 type_quals = TYPE_UNQUALIFIED;
03617
03618 member = **mangled == 'M';
03619 (*mangled)++;
03620
03621 string_append (&decl, ")");
03622
03623
03624
03625 if (**mangled != 'Q')
03626 string_prepend (&decl, SCOPE_STRING (work));
03627
03628 if (ISDIGIT ((unsigned char)**mangled))
03629 {
03630 n = consume_count (mangled);
03631 if (n == -1
03632 || (int) strlen (*mangled) < n)
03633 {
03634 success = 0;
03635 break;
03636 }
03637 string_prependn (&decl, *mangled, n);
03638 *mangled += n;
03639 }
03640 else if (**mangled == 'X' || **mangled == 'Y')
03641 {
03642 string temp;
03643 do_type (work, mangled, &temp);
03644 string_prepends (&decl, &temp);
03645 string_delete (&temp);
03646 }
03647 else if (**mangled == 't')
03648 {
03649 string temp;
03650 string_init (&temp);
03651 success = demangle_template (work, mangled, &temp,
03652 NULL, 1, 1);
03653 if (success)
03654 {
03655 string_prependn (&decl, temp.b, temp.p - temp.b);
03656 string_delete (&temp);
03657 }
03658 else
03659 break;
03660 }
03661 else if (**mangled == 'Q')
03662 {
03663 success = demangle_qualified (work, mangled, &decl,
03664 0,
03665 0);
03666 if (!success)
03667 break;
03668 }
03669 else
03670 {
03671 success = 0;
03672 break;
03673 }
03674
03675 string_prepend (&decl, "(");
03676 if (member)
03677 {
03678 switch (**mangled)
03679 {
03680 case 'C':
03681 case 'V':
03682 case 'u':
03683 type_quals |= code_for_qualifier (**mangled);
03684 (*mangled)++;
03685 break;
03686
03687 default:
03688 break;
03689 }
03690
03691 if (*(*mangled)++ != 'F')
03692 {
03693 success = 0;
03694 break;
03695 }
03696 }
03697 if ((member && !demangle_nested_args (work, mangled, &decl))
03698 || **mangled != '_')
03699 {
03700 success = 0;
03701 break;
03702 }
03703 (*mangled)++;
03704 if (! PRINT_ANSI_QUALIFIERS)
03705 {
03706 break;
03707 }
03708 if (type_quals != TYPE_UNQUALIFIED)
03709 {
03710 APPEND_BLANK (&decl);
03711 string_append (&decl, qualifier_string (type_quals));
03712 }
03713 break;
03714 }
03715 case 'G':
03716 (*mangled)++;
03717 break;
03718
03719 case 'C':
03720 case 'V':
03721 case 'u':
03722 if (PRINT_ANSI_QUALIFIERS)
03723 {
03724 if (!STRING_EMPTY (&decl))
03725 string_prepend (&decl, " ");
03726
03727 string_prepend (&decl, demangle_qualifier (**mangled));
03728 }
03729 (*mangled)++;
03730 break;
03731
03732
03733
03734
03735
03736 default:
03737 done = 1;
03738 break;
03739 }
03740 }
03741
03742 if (success) switch (**mangled)
03743 {
03744
03745 case 'Q':
03746 case 'K':
03747 {
03748 success = demangle_qualified (work, mangled, result, 0, 1);
03749 break;
03750 }
03751
03752
03753 case 'B':
03754 (*mangled)++;
03755 if (!get_count (mangled, &n) || n >= work -> numb)
03756 success = 0;
03757 else
03758 string_append (result, work->btypevec[n]);
03759 break;
03760
03761 case 'X':
03762 case 'Y':
03763
03764 {
03765 int idx;
03766
03767 (*mangled)++;
03768 idx = consume_count_with_underscores (mangled);
03769
03770 if (idx == -1
03771 || (work->tmpl_argvec && idx >= work->ntmpl_args)
03772 || consume_count_with_underscores (mangled) == -1)
03773 {
03774 success = 0;
03775 break;
03776 }
03777
03778 if (work->tmpl_argvec)
03779 string_append (result, work->tmpl_argvec[idx]);
03780 else
03781 string_append_template_idx (result, idx);
03782
03783 success = 1;
03784 }
03785 break;
03786
03787 default:
03788 success = demangle_fund_type (work, mangled, result);
03789 if (tk == tk_none)
03790 tk = (type_kind_t) success;
03791 break;
03792 }
03793
03794 if (success)
03795 {
03796 if (!STRING_EMPTY (&decl))
03797 {
03798 string_append (result, " ");
03799 string_appends (result, &decl);
03800 }
03801 }
03802 else
03803 string_delete (result);
03804 string_delete (&decl);
03805
03806 if (success)
03807
03808 return (int) ((tk == tk_none) ? tk_integral : tk);
03809 else
03810 return 0;
03811 }
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826 static int
03827 demangle_fund_type (work, mangled, result)
03828 struct work_stuff *work;
03829 const char **mangled;
03830 string *result;
03831 {
03832 int done = 0;
03833 int success = 1;
03834 char buf[10];
03835 unsigned int dec = 0;
03836 type_kind_t tk = tk_integral;
03837
03838
03839
03840 while (!done)
03841 {
03842 switch (**mangled)
03843 {
03844 case 'C':
03845 case 'V':
03846 case 'u':
03847 if (PRINT_ANSI_QUALIFIERS)
03848 {
03849 if (!STRING_EMPTY (result))
03850 string_prepend (result, " ");
03851 string_prepend (result, demangle_qualifier (**mangled));
03852 }
03853 (*mangled)++;
03854 break;
03855 case 'U':
03856 (*mangled)++;
03857 APPEND_BLANK (result);
03858 string_append (result, "unsigned");
03859 break;
03860 case 'S':
03861 (*mangled)++;
03862 APPEND_BLANK (result);
03863 string_append (result, "signed");
03864 break;
03865 case 'J':
03866 (*mangled)++;
03867 APPEND_BLANK (result);
03868 string_append (result, "__complex");
03869 break;
03870 default:
03871 done = 1;
03872 break;
03873 }
03874 }
03875
03876
03877
03878 switch (**mangled)
03879 {
03880 case '\0':
03881 case '_':
03882 break;
03883 case 'v':
03884 (*mangled)++;
03885 APPEND_BLANK (result);
03886 string_append (result, "void");
03887 break;
03888 case 'x':
03889 (*mangled)++;
03890 APPEND_BLANK (result);
03891 string_append (result, "long long");
03892 break;
03893 case 'l':
03894 (*mangled)++;
03895 APPEND_BLANK (result);
03896 string_append (result, "long");
03897 break;
03898 case 'i':
03899 (*mangled)++;
03900 APPEND_BLANK (result);
03901 string_append (result, "int");
03902 break;
03903 case 's':
03904 (*mangled)++;
03905 APPEND_BLANK (result);
03906 string_append (result, "short");
03907 break;
03908 case 'b':
03909 (*mangled)++;
03910 APPEND_BLANK (result);
03911 string_append (result, "bool");
03912 tk = tk_bool;
03913 break;
03914 case 'c':
03915 (*mangled)++;
03916 APPEND_BLANK (result);
03917 string_append (result, "char");
03918 tk = tk_char;
03919 break;
03920 case 'w':
03921 (*mangled)++;
03922 APPEND_BLANK (result);
03923 string_append (result, "wchar_t");
03924 tk = tk_char;
03925 break;
03926 case 'r':
03927 (*mangled)++;
03928 APPEND_BLANK (result);
03929 string_append (result, "long double");
03930 tk = tk_real;
03931 break;
03932 case 'd':
03933 (*mangled)++;
03934 APPEND_BLANK (result);
03935 string_append (result, "double");
03936 tk = tk_real;
03937 break;
03938 case 'f':
03939 (*mangled)++;
03940 APPEND_BLANK (result);
03941 string_append (result, "float");
03942 tk = tk_real;
03943 break;
03944 case 'G':
03945 (*mangled)++;
03946 if (!ISDIGIT ((unsigned char)**mangled))
03947 {
03948 success = 0;
03949 break;
03950 }
03951 case 'I':
03952 (*mangled)++;
03953 if (**mangled == '_')
03954 {
03955 int i;
03956 (*mangled)++;
03957 for (i = 0;
03958 i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
03959 (*mangled)++, i++)
03960 buf[i] = **mangled;
03961 if (**mangled != '_')
03962 {
03963 success = 0;
03964 break;
03965 }
03966 buf[i] = '\0';
03967 (*mangled)++;
03968 }
03969 else
03970 {
03971 strncpy (buf, *mangled, 2);
03972 buf[2] = '\0';
03973 *mangled += min (strlen (*mangled), 2);
03974 }
03975 sscanf (buf, "%x", &dec);
03976 sprintf (buf, "int%u_t", dec);
03977 APPEND_BLANK (result);
03978 string_append (result, buf);
03979 break;
03980
03981
03982
03983 case '0':
03984 case '1':
03985 case '2':
03986 case '3':
03987 case '4':
03988 case '5':
03989 case '6':
03990 case '7':
03991 case '8':
03992 case '9':
03993 {
03994 int bindex = register_Btype (work);
03995 string btype;
03996 string_init (&btype);
03997 if (demangle_class_name (work, mangled, &btype)) {
03998 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
03999 APPEND_BLANK (result);
04000 string_appends (result, &btype);
04001 }
04002 else
04003 success = 0;
04004 string_delete (&btype);
04005 break;
04006 }
04007 case 't':
04008 {
04009 string btype;
04010 string_init (&btype);
04011 success = demangle_template (work, mangled, &btype, 0, 1, 1);
04012 string_appends (result, &btype);
04013 string_delete (&btype);
04014 break;
04015 }
04016 default:
04017 success = 0;
04018 break;
04019 }
04020
04021 return success ? ((int) tk) : 0;
04022 }
04023
04024
04025
04026
04027
04028 static int
04029 do_hpacc_template_const_value (work, mangled, result)
04030 struct work_stuff *work ATTRIBUTE_UNUSED;
04031 const char **mangled;
04032 string *result;
04033 {
04034 int unsigned_const;
04035
04036 if (**mangled != 'U' && **mangled != 'S')
04037 return 0;
04038
04039 unsigned_const = (**mangled == 'U');
04040
04041 (*mangled)++;
04042
04043 switch (**mangled)
04044 {
04045 case 'N':
04046 string_append (result, "-");
04047
04048 case 'P':
04049 (*mangled)++;
04050 break;
04051 case 'M':
04052
04053 string_append (result, "-2147483648");
04054 (*mangled)++;
04055 return 1;
04056 default:
04057 return 0;
04058 }
04059
04060
04061 if (!(ISDIGIT ((unsigned char)**mangled)))
04062 return 0;
04063
04064
04065
04066 while (ISDIGIT ((unsigned char)**mangled))
04067 {
04068 char_str[0] = **mangled;
04069 string_append (result, char_str);
04070 (*mangled)++;
04071 }
04072
04073 if (unsigned_const)
04074 string_append (result, "U");
04075
04076
04077
04078
04079 return 1;
04080 }
04081
04082
04083
04084
04085 static int
04086 do_hpacc_template_literal (work, mangled, result)
04087 struct work_stuff *work;
04088 const char **mangled;
04089 string *result;
04090 {
04091 int literal_len = 0;
04092 char * recurse;
04093 char * recurse_dem;
04094
04095 if (**mangled != 'A')
04096 return 0;
04097
04098 (*mangled)++;
04099
04100 literal_len = consume_count (mangled);
04101
04102 if (literal_len <= 0)
04103 return 0;
04104
04105
04106
04107 string_append (result, "&");
04108
04109
04110 recurse = (char *) xmalloc (literal_len + 1);
04111 memcpy (recurse, *mangled, literal_len);
04112 recurse[literal_len] = '\000';
04113
04114 recurse_dem = cplus_demangle (recurse, work->options);
04115
04116 if (recurse_dem)
04117 {
04118 string_append (result, recurse_dem);
04119 free (recurse_dem);
04120 }
04121 else
04122 {
04123 string_appendn (result, *mangled, literal_len);
04124 }
04125 (*mangled) += literal_len;
04126 free (recurse);
04127
04128 return 1;
04129 }
04130
04131 static int
04132 snarf_numeric_literal (args, arg)
04133 const char ** args;
04134 string * arg;
04135 {
04136 if (**args == '-')
04137 {
04138 char_str[0] = '-';
04139 string_append (arg, char_str);
04140 (*args)++;
04141 }
04142 else if (**args == '+')
04143 (*args)++;
04144
04145 if (!ISDIGIT ((unsigned char)**args))
04146 return 0;
04147
04148 while (ISDIGIT ((unsigned char)**args))
04149 {
04150 char_str[0] = **args;
04151 string_append (arg, char_str);
04152 (*args)++;
04153 }
04154
04155 return 1;
04156 }
04157
04158
04159
04160
04161
04162 static int
04163 do_arg (work, mangled, result)
04164 struct work_stuff *work;
04165 const char **mangled;
04166 string *result;
04167 {
04168
04169
04170 const char *start = *mangled;
04171
04172 string_init (result);
04173
04174 if (work->nrepeats > 0)
04175 {
04176 --work->nrepeats;
04177
04178 if (work->previous_argument == 0)
04179 return 0;
04180
04181
04182 string_appends (result, work->previous_argument);
04183 return 1;
04184 }
04185
04186 if (**mangled == 'n')
04187 {
04188
04189 (*mangled)++;
04190 work->nrepeats = consume_count(mangled);
04191
04192 if (work->nrepeats <= 0)
04193
04194 return 0;
04195
04196 if (work->nrepeats > 9)
04197 {
04198 if (**mangled != '_')
04199
04200
04201 return 0;
04202 else
04203 (*mangled)++;
04204 }
04205
04206
04207 return do_arg (work, mangled, result);
04208 }
04209
04210
04211
04212
04213
04214 if (work->previous_argument)
04215 string_delete (work->previous_argument);
04216 else
04217 work->previous_argument = (string*) xmalloc (sizeof (string));
04218
04219 if (!do_type (work, mangled, work->previous_argument))
04220 return 0;
04221
04222 string_appends (result, work->previous_argument);
04223
04224 remember_type (work, start, *mangled - start);
04225 return 1;
04226 }
04227
04228 static void
04229 remember_type (work, start, len)
04230 struct work_stuff *work;
04231 const char *start;
04232 int len;
04233 {
04234 char *tem;
04235
04236 if (work->forgetting_types)
04237 return;
04238
04239 if (work -> ntypes >= work -> typevec_size)
04240 {
04241 if (work -> typevec_size == 0)
04242 {
04243 work -> typevec_size = 3;
04244 work -> typevec
04245 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
04246 }
04247 else
04248 {
04249 work -> typevec_size *= 2;
04250 work -> typevec
04251 = (char **) xrealloc ((char *)work -> typevec,
04252 sizeof (char *) * work -> typevec_size);
04253 }
04254 }
04255 tem = xmalloc (len + 1);
04256 memcpy (tem, start, len);
04257 tem[len] = '\0';
04258 work -> typevec[work -> ntypes++] = tem;
04259 }
04260
04261
04262
04263 static void
04264 remember_Ktype (work, start, len)
04265 struct work_stuff *work;
04266 const char *start;
04267 int len;
04268 {
04269 char *tem;
04270
04271 if (work -> numk >= work -> ksize)
04272 {
04273 if (work -> ksize == 0)
04274 {
04275 work -> ksize = 5;
04276 work -> ktypevec
04277 = (char **) xmalloc (sizeof (char *) * work -> ksize);
04278 }
04279 else
04280 {
04281 work -> ksize *= 2;
04282 work -> ktypevec
04283 = (char **) xrealloc ((char *)work -> ktypevec,
04284 sizeof (char *) * work -> ksize);
04285 }
04286 }
04287 tem = xmalloc (len + 1);
04288 memcpy (tem, start, len);
04289 tem[len] = '\0';
04290 work -> ktypevec[work -> numk++] = tem;
04291 }
04292
04293
04294
04295
04296
04297 static int
04298 register_Btype (work)
04299 struct work_stuff *work;
04300 {
04301 int ret;
04302
04303 if (work -> numb >= work -> bsize)
04304 {
04305 if (work -> bsize == 0)
04306 {
04307 work -> bsize = 5;
04308 work -> btypevec
04309 = (char **) xmalloc (sizeof (char *) * work -> bsize);
04310 }
04311 else
04312 {
04313 work -> bsize *= 2;
04314 work -> btypevec
04315 = (char **) xrealloc ((char *)work -> btypevec,
04316 sizeof (char *) * work -> bsize);
04317 }
04318 }
04319 ret = work -> numb++;
04320 work -> btypevec[ret] = NULL;
04321 return(ret);
04322 }
04323
04324
04325
04326 static void
04327 remember_Btype (work, start, len, index)
04328 struct work_stuff *work;
04329 const char *start;
04330 int len, index;
04331 {
04332 char *tem;
04333
04334 tem = xmalloc (len + 1);
04335 memcpy (tem, start, len);
04336 tem[len] = '\0';
04337 work -> btypevec[index] = tem;
04338 }
04339
04340
04341 static void
04342 forget_B_and_K_types (work)
04343 struct work_stuff *work;
04344 {
04345 int i;
04346
04347 while (work -> numk > 0)
04348 {
04349 i = --(work -> numk);
04350 if (work -> ktypevec[i] != NULL)
04351 {
04352 free (work -> ktypevec[i]);
04353 work -> ktypevec[i] = NULL;
04354 }
04355 }
04356
04357 while (work -> numb > 0)
04358 {
04359 i = --(work -> numb);
04360 if (work -> btypevec[i] != NULL)
04361 {
04362 free (work -> btypevec[i]);
04363 work -> btypevec[i] = NULL;
04364 }
04365 }
04366 }
04367
04368
04369 static void
04370 forget_types (work)
04371 struct work_stuff *work;
04372 {
04373 int i;
04374
04375 while (work -> ntypes > 0)
04376 {
04377 i = --(work -> ntypes);
04378 if (work -> typevec[i] != NULL)
04379 {
04380 free (work -> typevec[i]);
04381 work -> typevec[i] = NULL;
04382 }
04383 }
04384 }
04385
04386
04387
04388
04389
04390
04391
04392
04393
04394
04395
04396
04397
04398
04399
04400
04401
04402
04403
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428 static int
04429 demangle_args (work, mangled, declp)
04430 struct work_stuff *work;
04431 const char **mangled;
04432 string *declp;
04433 {
04434 string arg;
04435 int need_comma = 0;
04436 int r;
04437 int t;
04438 const char *tem;
04439 char temptype;
04440
04441 if (PRINT_ARG_TYPES)
04442 {
04443 string_append (declp, "(");
04444 if (**mangled == '\0')
04445 {
04446 string_append (declp, "void");
04447 }
04448 }
04449
04450 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
04451 || work->nrepeats > 0)
04452 {
04453 if ((**mangled == 'N') || (**mangled == 'T'))
04454 {
04455 temptype = *(*mangled)++;
04456
04457 if (temptype == 'N')
04458 {
04459 if (!get_count (mangled, &r))
04460 {
04461 return (0);
04462 }
04463 }
04464 else
04465 {
04466 r = 1;
04467 }
04468 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
04469 {
04470
04471
04472
04473
04474
04475
04476 if ((t = consume_count(mangled)) <= 0)
04477 {
04478 return (0);
04479 }
04480 }
04481 else
04482 {
04483 if (!get_count (mangled, &t))
04484 {
04485 return (0);
04486 }
04487 }
04488 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
04489 {
04490 t--;
04491 }
04492
04493
04494 if ((t < 0) || (t >= work -> ntypes))
04495 {
04496 return (0);
04497 }
04498 while (work->nrepeats > 0 || --r >= 0)
04499 {
04500 tem = work -> typevec[t];
04501 if (need_comma && PRINT_ARG_TYPES)
04502 {
04503 string_append (declp, ", ");
04504 }
04505 if (!do_arg (work, &tem, &arg))
04506 {
04507 return (0);
04508 }
04509 if (PRINT_ARG_TYPES)
04510 {
04511 string_appends (declp, &arg);
04512 }
04513 string_delete (&arg);
04514 need_comma = 1;
04515 }
04516 }
04517 else
04518 {
04519 if (need_comma && PRINT_ARG_TYPES)
04520 string_append (declp, ", ");
04521 if (!do_arg (work, mangled, &arg))
04522 return (0);
04523 if (PRINT_ARG_TYPES)
04524 string_appends (declp, &arg);
04525 string_delete (&arg);
04526 need_comma = 1;
04527 }
04528 }
04529
04530 if (**mangled == 'e')
04531 {
04532 (*mangled)++;
04533 if (PRINT_ARG_TYPES)
04534 {
04535 if (need_comma)
04536 {
04537 string_append (declp, ",");
04538 }
04539 string_append (declp, "...");
04540 }
04541 }
04542
04543 if (PRINT_ARG_TYPES)
04544 {
04545 string_append (declp, ")");
04546 }
04547 return (1);
04548 }
04549
04550
04551
04552
04553 static int
04554 demangle_nested_args (work, mangled, declp)
04555 struct work_stuff *work;
04556 const char **mangled;
04557 string *declp;
04558 {
04559 string* saved_previous_argument;
04560 int result;
04561 int saved_nrepeats;
04562
04563
04564
04565
04566
04567 ++work->forgetting_types;
04568
04569
04570
04571 saved_previous_argument = work->previous_argument;
04572 saved_nrepeats = work->nrepeats;
04573 work->previous_argument = 0;
04574 work->nrepeats = 0;
04575
04576
04577 result = demangle_args (work, mangled, declp);
04578
04579
04580 if (work->previous_argument)
04581 {
04582 string_delete (work->previous_argument);
04583 free ((char *) work->previous_argument);
04584 }
04585 work->previous_argument = saved_previous_argument;
04586 --work->forgetting_types;
04587 work->nrepeats = saved_nrepeats;
04588
04589 return result;
04590 }
04591
04592 static void
04593 demangle_function_name (work, mangled, declp, scan)
04594 struct work_stuff *work;
04595 const char **mangled;
04596 string *declp;
04597 const char *scan;
04598 {
04599 size_t i;
04600 string type;
04601 const char *tem;
04602
04603 string_appendn (declp, (*mangled), scan - (*mangled));
04604 string_need (declp, 1);
04605 *(declp -> p) = '\0';
04606
04607
04608
04609
04610
04611 (*mangled) = scan + 2;
04612
04613
04614
04615
04616
04617 if (HP_DEMANGLING && (**mangled == 'X'))
04618 {
04619 demangle_arm_hp_template (work, mangled, 0, declp);
04620
04621 }
04622
04623 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
04624 {
04625
04626
04627
04628
04629
04630
04631 if (strcmp (declp -> b, "__ct") == 0)
04632 {
04633 work -> constructor += 1;
04634 string_clear (declp);
04635 return;
04636 }
04637 else if (strcmp (declp -> b, "__dt") == 0)
04638 {
04639 work -> destructor += 1;
04640 string_clear (declp);
04641 return;
04642 }
04643 }
04644
04645 if (declp->p - declp->b >= 3
04646 && declp->b[0] == 'o'
04647 && declp->b[1] == 'p'
04648 && strchr (cplus_markers, declp->b[2]) != NULL)
04649 {
04650
04651 if (declp->p - declp->b >= 10
04652 && memcmp (declp->b + 3, "assign_", 7) == 0)
04653 {
04654 for (i = 0; i < ARRAY_SIZE (optable); i++)
04655 {
04656 int len = declp->p - declp->b - 10;
04657 if ((int) strlen (optable[i].in) == len
04658 && memcmp (optable[i].in, declp->b + 10, len) == 0)
04659 {
04660 string_clear (declp);
04661 string_append (declp, "operator");
04662 string_append (declp, optable[i].out);
04663 string_append (declp, "=");
04664 break;
04665 }
04666 }
04667 }
04668 else
04669 {
04670 for (i = 0; i < ARRAY_SIZE (optable); i++)
04671 {
04672 int len = declp->p - declp->b - 3;
04673 if ((int) strlen (optable[i].in) == len
04674 && memcmp (optable[i].in, declp->b + 3, len) == 0)
04675 {
04676 string_clear (declp);
04677 string_append (declp, "operator");
04678 string_append (declp, optable[i].out);
04679 break;
04680 }
04681 }
04682 }
04683 }
04684 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
04685 && strchr (cplus_markers, declp->b[4]) != NULL)
04686 {
04687
04688 tem = declp->b + 5;
04689 if (do_type (work, &tem, &type))
04690 {
04691 string_clear (declp);
04692 string_append (declp, "operator ");
04693 string_appends (declp, &type);
04694 string_delete (&type);
04695 }
04696 }
04697 else if (declp->b[0] == '_' && declp->b[1] == '_'
04698 && declp->b[2] == 'o' && declp->b[3] == 'p')
04699 {
04700
04701
04702 tem = declp->b + 4;
04703 if (do_type (work, &tem, &type))
04704 {
04705 string_clear (declp);
04706 string_append (declp, "operator ");
04707 string_appends (declp, &type);
04708 string_delete (&type);
04709 }
04710 }
04711 else if (declp->b[0] == '_' && declp->b[1] == '_'
04712 && ISLOWER((unsigned char)declp->b[2])
04713 && ISLOWER((unsigned char)declp->b[3]))
04714 {
04715 if (declp->b[4] == '\0')
04716 {
04717
04718 for (i = 0; i < ARRAY_SIZE (optable); i++)
04719 {
04720 if (strlen (optable[i].in) == 2
04721 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
04722 {
04723 string_clear (declp);
04724 string_append (declp, "operator");
04725 string_append (declp, optable[i].out);
04726 break;
04727 }
04728 }
04729 }
04730 else
04731 {
04732 if (declp->b[2] == 'a' && declp->b[5] == '\0')
04733 {
04734
04735 for (i = 0; i < ARRAY_SIZE (optable); i++)
04736 {
04737 if (strlen (optable[i].in) == 3
04738 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
04739 {
04740 string_clear (declp);
04741 string_append (declp, "operator");
04742 string_append (declp, optable[i].out);
04743 break;
04744 }
04745 }
04746 }
04747 }
04748 }
04749 }
04750
04751
04752
04753 static void
04754 string_need (s, n)
04755 string *s;
04756 int n;
04757 {
04758 int tem;
04759
04760 if (s->b == NULL)
04761 {
04762 if (n < 32)
04763 {
04764 n = 32;
04765 }
04766 s->p = s->b = xmalloc (n);
04767 s->e = s->b + n;
04768 }
04769 else if (s->e - s->p < n)
04770 {
04771 tem = s->p - s->b;
04772 n += tem;
04773 n *= 2;
04774 s->b = xrealloc (s->b, n);
04775 s->p = s->b + tem;
04776 s->e = s->b + n;
04777 }
04778 }
04779
04780 static void
04781 string_delete (s)
04782 string *s;
04783 {
04784 if (s->b != NULL)
04785 {
04786 free (s->b);
04787 s->b = s->e = s->p = NULL;
04788 }
04789 }
04790
04791 static void
04792 string_init (s)
04793 string *s;
04794 {
04795 s->b = s->p = s->e = NULL;
04796 }
04797
04798 static void
04799 string_clear (s)
04800 string *s;
04801 {
04802 s->p = s->b;
04803 }
04804
04805 #if 0
04806
04807 static int
04808 string_empty (s)
04809 string *s;
04810 {
04811 return (s->b == s->p);
04812 }
04813
04814 #endif
04815
04816 static void
04817 string_append (p, s)
04818 string *p;
04819 const char *s;
04820 {
04821 int n;
04822 if (s == NULL || *s == '\0')
04823 return;
04824 n = strlen (s);
04825 string_need (p, n);
04826 memcpy (p->p, s, n);
04827 p->p += n;
04828 }
04829
04830 static void
04831 string_appends (p, s)
04832 string *p, *s;
04833 {
04834 int n;
04835
04836 if (s->b != s->p)
04837 {
04838 n = s->p - s->b;
04839 string_need (p, n);
04840 memcpy (p->p, s->b, n);
04841 p->p += n;
04842 }
04843 }
04844
04845 static void
04846 string_appendn (p, s, n)
04847 string *p;
04848 const char *s;
04849 int n;
04850 {
04851 if (n != 0)
04852 {
04853 string_need (p, n);
04854 memcpy (p->p, s, n);
04855 p->p += n;
04856 }
04857 }
04858
04859 static void
04860 string_prepend (p, s)
04861 string *p;
04862 const char *s;
04863 {
04864 if (s != NULL && *s != '\0')
04865 {
04866 string_prependn (p, s, strlen (s));
04867 }
04868 }
04869
04870 static void
04871 string_prepends (p, s)
04872 string *p, *s;
04873 {
04874 if (s->b != s->p)
04875 {
04876 string_prependn (p, s->b, s->p - s->b);
04877 }
04878 }
04879
04880 static void
04881 string_prependn (p, s, n)
04882 string *p;
04883 const char *s;
04884 int n;
04885 {
04886 char *q;
04887
04888 if (n != 0)
04889 {
04890 string_need (p, n);
04891 for (q = p->p - 1; q >= p->b; q--)
04892 {
04893 q[n] = q[0];
04894 }
04895 memcpy (p->b, s, n);
04896 p->p += n;
04897 }
04898 }
04899
04900 static void
04901 string_append_template_idx (s, idx)
04902 string *s;
04903 int idx;
04904 {
04905 char buf[INTBUF_SIZE + 1 ];
04906 sprintf(buf, "T%d", idx);
04907 string_append (s, buf);
04908 }