1169695Skan/* Demangler for GNU C++ 2169695Skan Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999, 3169695Skan 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. 4169695Skan Written by James Clark (jjc@jclark.uucp) 5169695Skan Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling 6169695Skan Modified by Satish Pai (pai@apollo.hp.com) for HP demangling 7169695Skan 8169695SkanThis file is part of the libiberty library. 9169695SkanLibiberty is free software; you can redistribute it and/or 10169695Skanmodify it under the terms of the GNU Library General Public 11169695SkanLicense as published by the Free Software Foundation; either 12169695Skanversion 2 of the License, or (at your option) any later version. 13169695Skan 14169695SkanIn addition to the permissions in the GNU Library General Public 15169695SkanLicense, the Free Software Foundation gives you unlimited permission 16169695Skanto link the compiled version of this file into combinations with other 17169695Skanprograms, and to distribute those combinations without any restriction 18169695Skancoming from the use of this file. (The Library Public License 19169695Skanrestrictions do apply in other respects; for example, they cover 20169695Skanmodification of the file, and distribution when not linked into a 21169695Skancombined executable.) 22169695Skan 23169695SkanLibiberty is distributed in the hope that it will be useful, 24169695Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of 25169695SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 26169695SkanLibrary General Public License for more details. 27169695Skan 28169695SkanYou should have received a copy of the GNU Library General Public 29169695SkanLicense along with libiberty; see the file COPYING.LIB. If 30169695Skannot, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 31169695SkanBoston, MA 02110-1301, USA. */ 32169695Skan 33169695Skan/* This file exports two functions; cplus_mangle_opname and cplus_demangle. 34169695Skan 35169695Skan This file imports xmalloc and xrealloc, which are like malloc and 36169695Skan realloc except that they generate a fatal error if there is no 37169695Skan available memory. */ 38169695Skan 39169695Skan/* This file lives in both GCC and libiberty. When making changes, please 40169695Skan try not to break either. */ 41169695Skan 42169695Skan#ifdef HAVE_CONFIG_H 43169695Skan#include "config.h" 44169695Skan#endif 45169695Skan 46169695Skan#include "safe-ctype.h" 47169695Skan 48169695Skan#include <sys/types.h> 49169695Skan#include <string.h> 50169695Skan#include <stdio.h> 51169695Skan 52169695Skan#ifdef HAVE_STDLIB_H 53169695Skan#include <stdlib.h> 54169695Skan#else 55169695Skanchar * malloc (); 56169695Skanchar * realloc (); 57169695Skan#endif 58169695Skan 59169695Skan#include <demangle.h> 60169695Skan#undef CURRENT_DEMANGLING_STYLE 61169695Skan#define CURRENT_DEMANGLING_STYLE work->options 62169695Skan 63169695Skan#include "libiberty.h" 64169695Skan 65169695Skanstatic char *ada_demangle (const char *, int); 66169695Skan 67169695Skan#define min(X,Y) (((X) < (Y)) ? (X) : (Y)) 68169695Skan 69169695Skan/* A value at least one greater than the maximum number of characters 70169695Skan that will be output when using the `%d' format with `printf'. */ 71169695Skan#define INTBUF_SIZE 32 72169695Skan 73169695Skanextern void fancy_abort (void) ATTRIBUTE_NORETURN; 74169695Skan 75169695Skan/* In order to allow a single demangler executable to demangle strings 76169695Skan using various common values of CPLUS_MARKER, as well as any specific 77169695Skan one set at compile time, we maintain a string containing all the 78169695Skan commonly used ones, and check to see if the marker we are looking for 79169695Skan is in that string. CPLUS_MARKER is usually '$' on systems where the 80169695Skan assembler can deal with that. Where the assembler can't, it's usually 81169695Skan '.' (but on many systems '.' is used for other things). We put the 82169695Skan current defined CPLUS_MARKER first (which defaults to '$'), followed 83169695Skan by the next most common value, followed by an explicit '$' in case 84169695Skan the value of CPLUS_MARKER is not '$'. 85169695Skan 86169695Skan We could avoid this if we could just get g++ to tell us what the actual 87169695Skan cplus marker character is as part of the debug information, perhaps by 88169695Skan ensuring that it is the character that terminates the gcc<n>_compiled 89169695Skan marker symbol (FIXME). */ 90169695Skan 91169695Skan#if !defined (CPLUS_MARKER) 92169695Skan#define CPLUS_MARKER '$' 93169695Skan#endif 94169695Skan 95169695Skanenum demangling_styles current_demangling_style = auto_demangling; 96169695Skan 97169695Skanstatic char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' }; 98169695Skan 99169695Skanstatic char char_str[2] = { '\000', '\000' }; 100169695Skan 101169695Skanvoid 102169695Skanset_cplus_marker_for_demangling (int ch) 103169695Skan{ 104169695Skan cplus_markers[0] = ch; 105169695Skan} 106169695Skan 107169695Skantypedef struct string /* Beware: these aren't required to be */ 108169695Skan{ /* '\0' terminated. */ 109169695Skan char *b; /* pointer to start of string */ 110169695Skan char *p; /* pointer after last character */ 111169695Skan char *e; /* pointer after end of allocated space */ 112169695Skan} string; 113169695Skan 114169695Skan/* Stuff that is shared between sub-routines. 115169695Skan Using a shared structure allows cplus_demangle to be reentrant. */ 116169695Skan 117169695Skanstruct work_stuff 118169695Skan{ 119169695Skan int options; 120169695Skan char **typevec; 121169695Skan char **ktypevec; 122169695Skan char **btypevec; 123169695Skan int numk; 124169695Skan int numb; 125169695Skan int ksize; 126169695Skan int bsize; 127169695Skan int ntypes; 128169695Skan int typevec_size; 129169695Skan int constructor; 130169695Skan int destructor; 131169695Skan int static_type; /* A static member function */ 132169695Skan int temp_start; /* index in demangled to start of template args */ 133169695Skan int type_quals; /* The type qualifiers. */ 134169695Skan int dllimported; /* Symbol imported from a PE DLL */ 135169695Skan char **tmpl_argvec; /* Template function arguments. */ 136169695Skan int ntmpl_args; /* The number of template function arguments. */ 137169695Skan int forgetting_types; /* Nonzero if we are not remembering the types 138169695Skan we see. */ 139169695Skan string* previous_argument; /* The last function argument demangled. */ 140169695Skan int nrepeats; /* The number of times to repeat the previous 141169695Skan argument. */ 142169695Skan}; 143169695Skan 144169695Skan#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI) 145169695Skan#define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS) 146169695Skan 147169695Skanstatic const struct optable 148169695Skan{ 149169695Skan const char *const in; 150169695Skan const char *const out; 151169695Skan const int flags; 152169695Skan} optable[] = { 153169695Skan {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */ 154169695Skan {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */ 155169695Skan {"new", " new", 0}, /* old (1.91, and 1.x) */ 156169695Skan {"delete", " delete", 0}, /* old (1.91, and 1.x) */ 157169695Skan {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */ 158169695Skan {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */ 159169695Skan {"as", "=", DMGL_ANSI}, /* ansi */ 160169695Skan {"ne", "!=", DMGL_ANSI}, /* old, ansi */ 161169695Skan {"eq", "==", DMGL_ANSI}, /* old, ansi */ 162169695Skan {"ge", ">=", DMGL_ANSI}, /* old, ansi */ 163169695Skan {"gt", ">", DMGL_ANSI}, /* old, ansi */ 164169695Skan {"le", "<=", DMGL_ANSI}, /* old, ansi */ 165169695Skan {"lt", "<", DMGL_ANSI}, /* old, ansi */ 166169695Skan {"plus", "+", 0}, /* old */ 167169695Skan {"pl", "+", DMGL_ANSI}, /* ansi */ 168169695Skan {"apl", "+=", DMGL_ANSI}, /* ansi */ 169169695Skan {"minus", "-", 0}, /* old */ 170169695Skan {"mi", "-", DMGL_ANSI}, /* ansi */ 171169695Skan {"ami", "-=", DMGL_ANSI}, /* ansi */ 172169695Skan {"mult", "*", 0}, /* old */ 173169695Skan {"ml", "*", DMGL_ANSI}, /* ansi */ 174169695Skan {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */ 175169695Skan {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */ 176169695Skan {"convert", "+", 0}, /* old (unary +) */ 177169695Skan {"negate", "-", 0}, /* old (unary -) */ 178169695Skan {"trunc_mod", "%", 0}, /* old */ 179169695Skan {"md", "%", DMGL_ANSI}, /* ansi */ 180169695Skan {"amd", "%=", DMGL_ANSI}, /* ansi */ 181169695Skan {"trunc_div", "/", 0}, /* old */ 182169695Skan {"dv", "/", DMGL_ANSI}, /* ansi */ 183169695Skan {"adv", "/=", DMGL_ANSI}, /* ansi */ 184169695Skan {"truth_andif", "&&", 0}, /* old */ 185169695Skan {"aa", "&&", DMGL_ANSI}, /* ansi */ 186169695Skan {"truth_orif", "||", 0}, /* old */ 187169695Skan {"oo", "||", DMGL_ANSI}, /* ansi */ 188169695Skan {"truth_not", "!", 0}, /* old */ 189169695Skan {"nt", "!", DMGL_ANSI}, /* ansi */ 190169695Skan {"postincrement","++", 0}, /* old */ 191169695Skan {"pp", "++", DMGL_ANSI}, /* ansi */ 192169695Skan {"postdecrement","--", 0}, /* old */ 193169695Skan {"mm", "--", DMGL_ANSI}, /* ansi */ 194169695Skan {"bit_ior", "|", 0}, /* old */ 195169695Skan {"or", "|", DMGL_ANSI}, /* ansi */ 196169695Skan {"aor", "|=", DMGL_ANSI}, /* ansi */ 197169695Skan {"bit_xor", "^", 0}, /* old */ 198169695Skan {"er", "^", DMGL_ANSI}, /* ansi */ 199169695Skan {"aer", "^=", DMGL_ANSI}, /* ansi */ 200169695Skan {"bit_and", "&", 0}, /* old */ 201169695Skan {"ad", "&", DMGL_ANSI}, /* ansi */ 202169695Skan {"aad", "&=", DMGL_ANSI}, /* ansi */ 203169695Skan {"bit_not", "~", 0}, /* old */ 204169695Skan {"co", "~", DMGL_ANSI}, /* ansi */ 205169695Skan {"call", "()", 0}, /* old */ 206169695Skan {"cl", "()", DMGL_ANSI}, /* ansi */ 207169695Skan {"alshift", "<<", 0}, /* old */ 208169695Skan {"ls", "<<", DMGL_ANSI}, /* ansi */ 209169695Skan {"als", "<<=", DMGL_ANSI}, /* ansi */ 210169695Skan {"arshift", ">>", 0}, /* old */ 211169695Skan {"rs", ">>", DMGL_ANSI}, /* ansi */ 212169695Skan {"ars", ">>=", DMGL_ANSI}, /* ansi */ 213169695Skan {"component", "->", 0}, /* old */ 214169695Skan {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */ 215169695Skan {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */ 216169695Skan {"indirect", "*", 0}, /* old */ 217169695Skan {"method_call", "->()", 0}, /* old */ 218169695Skan {"addr", "&", 0}, /* old (unary &) */ 219169695Skan {"array", "[]", 0}, /* old */ 220169695Skan {"vc", "[]", DMGL_ANSI}, /* ansi */ 221169695Skan {"compound", ", ", 0}, /* old */ 222169695Skan {"cm", ", ", DMGL_ANSI}, /* ansi */ 223169695Skan {"cond", "?:", 0}, /* old */ 224169695Skan {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */ 225169695Skan {"max", ">?", 0}, /* old */ 226169695Skan {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */ 227169695Skan {"min", "<?", 0}, /* old */ 228169695Skan {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */ 229169695Skan {"nop", "", 0}, /* old (for operator=) */ 230169695Skan {"rm", "->*", DMGL_ANSI}, /* ansi */ 231169695Skan {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */ 232169695Skan}; 233169695Skan 234169695Skan/* These values are used to indicate the various type varieties. 235169695Skan They are all non-zero so that they can be used as `success' 236169695Skan values. */ 237169695Skantypedef enum type_kind_t 238169695Skan{ 239169695Skan tk_none, 240169695Skan tk_pointer, 241169695Skan tk_reference, 242169695Skan tk_integral, 243169695Skan tk_bool, 244169695Skan tk_char, 245169695Skan tk_real 246169695Skan} type_kind_t; 247169695Skan 248169695Skanconst struct demangler_engine libiberty_demanglers[] = 249169695Skan{ 250169695Skan { 251169695Skan NO_DEMANGLING_STYLE_STRING, 252169695Skan no_demangling, 253169695Skan "Demangling disabled" 254169695Skan } 255169695Skan , 256169695Skan { 257169695Skan AUTO_DEMANGLING_STYLE_STRING, 258169695Skan auto_demangling, 259169695Skan "Automatic selection based on executable" 260169695Skan } 261169695Skan , 262169695Skan { 263169695Skan GNU_DEMANGLING_STYLE_STRING, 264169695Skan gnu_demangling, 265169695Skan "GNU (g++) style demangling" 266169695Skan } 267169695Skan , 268169695Skan { 269169695Skan LUCID_DEMANGLING_STYLE_STRING, 270169695Skan lucid_demangling, 271169695Skan "Lucid (lcc) style demangling" 272169695Skan } 273169695Skan , 274169695Skan { 275169695Skan ARM_DEMANGLING_STYLE_STRING, 276169695Skan arm_demangling, 277169695Skan "ARM style demangling" 278169695Skan } 279169695Skan , 280169695Skan { 281169695Skan HP_DEMANGLING_STYLE_STRING, 282169695Skan hp_demangling, 283169695Skan "HP (aCC) style demangling" 284169695Skan } 285169695Skan , 286169695Skan { 287169695Skan EDG_DEMANGLING_STYLE_STRING, 288169695Skan edg_demangling, 289169695Skan "EDG style demangling" 290169695Skan } 291169695Skan , 292169695Skan { 293169695Skan GNU_V3_DEMANGLING_STYLE_STRING, 294169695Skan gnu_v3_demangling, 295169695Skan "GNU (g++) V3 ABI-style demangling" 296169695Skan } 297169695Skan , 298169695Skan { 299169695Skan JAVA_DEMANGLING_STYLE_STRING, 300169695Skan java_demangling, 301169695Skan "Java style demangling" 302169695Skan } 303169695Skan , 304169695Skan { 305169695Skan GNAT_DEMANGLING_STYLE_STRING, 306169695Skan gnat_demangling, 307169695Skan "GNAT style demangling" 308169695Skan } 309169695Skan , 310169695Skan { 311169695Skan NULL, unknown_demangling, NULL 312169695Skan } 313169695Skan}; 314169695Skan 315169695Skan#define STRING_EMPTY(str) ((str) -> b == (str) -> p) 316169695Skan#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \ 317169695Skan string_append(str, " ");} 318169695Skan#define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b)) 319169695Skan 320169695Skan/* The scope separator appropriate for the language being demangled. */ 321169695Skan 322169695Skan#define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::") 323169695Skan 324169695Skan#define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */ 325169695Skan#define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */ 326169695Skan 327169695Skan/* Prototypes for local functions */ 328169695Skan 329169695Skanstatic void delete_work_stuff (struct work_stuff *); 330169695Skan 331169695Skanstatic void delete_non_B_K_work_stuff (struct work_stuff *); 332169695Skan 333169695Skanstatic char *mop_up (struct work_stuff *, string *, int); 334169695Skan 335169695Skanstatic void squangle_mop_up (struct work_stuff *); 336169695Skan 337169695Skanstatic void work_stuff_copy_to_from (struct work_stuff *, struct work_stuff *); 338169695Skan 339169695Skan#if 0 340169695Skanstatic int 341169695Skandemangle_method_args (struct work_stuff *, const char **, string *); 342169695Skan#endif 343169695Skan 344169695Skanstatic char * 345169695Skaninternal_cplus_demangle (struct work_stuff *, const char *); 346169695Skan 347169695Skanstatic int 348169695Skandemangle_template_template_parm (struct work_stuff *work, 349169695Skan const char **, string *); 350169695Skan 351169695Skanstatic int 352169695Skandemangle_template (struct work_stuff *work, const char **, string *, 353169695Skan string *, int, int); 354169695Skan 355169695Skanstatic int 356169695Skanarm_pt (struct work_stuff *, const char *, int, const char **, 357169695Skan const char **); 358169695Skan 359169695Skanstatic int 360169695Skandemangle_class_name (struct work_stuff *, const char **, string *); 361169695Skan 362169695Skanstatic int 363169695Skandemangle_qualified (struct work_stuff *, const char **, string *, 364169695Skan int, int); 365169695Skan 366169695Skanstatic int demangle_class (struct work_stuff *, const char **, string *); 367169695Skan 368169695Skanstatic int demangle_fund_type (struct work_stuff *, const char **, string *); 369169695Skan 370169695Skanstatic int demangle_signature (struct work_stuff *, const char **, string *); 371169695Skan 372169695Skanstatic int demangle_prefix (struct work_stuff *, const char **, string *); 373169695Skan 374169695Skanstatic int gnu_special (struct work_stuff *, const char **, string *); 375169695Skan 376169695Skanstatic int arm_special (const char **, string *); 377169695Skan 378169695Skanstatic void string_need (string *, int); 379169695Skan 380169695Skanstatic void string_delete (string *); 381169695Skan 382169695Skanstatic void 383169695Skanstring_init (string *); 384169695Skan 385169695Skanstatic void string_clear (string *); 386169695Skan 387169695Skan#if 0 388169695Skanstatic int string_empty (string *); 389169695Skan#endif 390169695Skan 391169695Skanstatic void string_append (string *, const char *); 392169695Skan 393169695Skanstatic void string_appends (string *, string *); 394169695Skan 395169695Skanstatic void string_appendn (string *, const char *, int); 396169695Skan 397169695Skanstatic void string_prepend (string *, const char *); 398169695Skan 399169695Skanstatic void string_prependn (string *, const char *, int); 400169695Skan 401169695Skanstatic void string_append_template_idx (string *, int); 402169695Skan 403169695Skanstatic int get_count (const char **, int *); 404169695Skan 405169695Skanstatic int consume_count (const char **); 406169695Skan 407169695Skanstatic int consume_count_with_underscores (const char**); 408169695Skan 409169695Skanstatic int demangle_args (struct work_stuff *, const char **, string *); 410169695Skan 411169695Skanstatic int demangle_nested_args (struct work_stuff*, const char**, string*); 412169695Skan 413169695Skanstatic int do_type (struct work_stuff *, const char **, string *); 414169695Skan 415169695Skanstatic int do_arg (struct work_stuff *, const char **, string *); 416169695Skan 417169695Skanstatic void 418169695Skandemangle_function_name (struct work_stuff *, const char **, string *, 419169695Skan const char *); 420169695Skan 421169695Skanstatic int 422169695Skaniterate_demangle_function (struct work_stuff *, 423169695Skan const char **, string *, const char *); 424169695Skan 425169695Skanstatic void remember_type (struct work_stuff *, const char *, int); 426169695Skan 427169695Skanstatic void remember_Btype (struct work_stuff *, const char *, int, int); 428169695Skan 429169695Skanstatic int register_Btype (struct work_stuff *); 430169695Skan 431169695Skanstatic void remember_Ktype (struct work_stuff *, const char *, int); 432169695Skan 433169695Skanstatic void forget_types (struct work_stuff *); 434169695Skan 435169695Skanstatic void forget_B_and_K_types (struct work_stuff *); 436169695Skan 437169695Skanstatic void string_prepends (string *, string *); 438169695Skan 439169695Skanstatic int 440169695Skandemangle_template_value_parm (struct work_stuff*, const char**, 441169695Skan string*, type_kind_t); 442169695Skan 443169695Skanstatic int 444169695Skando_hpacc_template_const_value (struct work_stuff *, const char **, string *); 445169695Skan 446169695Skanstatic int 447169695Skando_hpacc_template_literal (struct work_stuff *, const char **, string *); 448169695Skan 449169695Skanstatic int snarf_numeric_literal (const char **, string *); 450169695Skan 451169695Skan/* There is a TYPE_QUAL value for each type qualifier. They can be 452169695Skan combined by bitwise-or to form the complete set of qualifiers for a 453169695Skan type. */ 454169695Skan 455169695Skan#define TYPE_UNQUALIFIED 0x0 456169695Skan#define TYPE_QUAL_CONST 0x1 457169695Skan#define TYPE_QUAL_VOLATILE 0x2 458169695Skan#define TYPE_QUAL_RESTRICT 0x4 459169695Skan 460169695Skanstatic int code_for_qualifier (int); 461169695Skan 462169695Skanstatic const char* qualifier_string (int); 463169695Skan 464169695Skanstatic const char* demangle_qualifier (int); 465169695Skan 466169695Skanstatic int demangle_expression (struct work_stuff *, const char **, string *, 467169695Skan type_kind_t); 468169695Skan 469169695Skanstatic int 470169695Skandemangle_integral_value (struct work_stuff *, const char **, string *); 471169695Skan 472169695Skanstatic int 473169695Skandemangle_real_value (struct work_stuff *, const char **, string *); 474169695Skan 475169695Skanstatic void 476169695Skandemangle_arm_hp_template (struct work_stuff *, const char **, int, string *); 477169695Skan 478169695Skanstatic void 479169695Skanrecursively_demangle (struct work_stuff *, const char **, string *, int); 480169695Skan 481169695Skanstatic void grow_vect (char **, size_t *, size_t, int); 482169695Skan 483169695Skan/* Translate count to integer, consuming tokens in the process. 484169695Skan Conversion terminates on the first non-digit character. 485169695Skan 486169695Skan Trying to consume something that isn't a count results in no 487169695Skan consumption of input and a return of -1. 488169695Skan 489169695Skan Overflow consumes the rest of the digits, and returns -1. */ 490169695Skan 491169695Skanstatic int 492169695Skanconsume_count (const char **type) 493169695Skan{ 494169695Skan int count = 0; 495169695Skan 496169695Skan if (! ISDIGIT ((unsigned char)**type)) 497169695Skan return -1; 498169695Skan 499169695Skan while (ISDIGIT ((unsigned char)**type)) 500169695Skan { 501169695Skan count *= 10; 502169695Skan 503169695Skan /* Check for overflow. 504169695Skan We assume that count is represented using two's-complement; 505169695Skan no power of two is divisible by ten, so if an overflow occurs 506169695Skan when multiplying by ten, the result will not be a multiple of 507169695Skan ten. */ 508169695Skan if ((count % 10) != 0) 509169695Skan { 510169695Skan while (ISDIGIT ((unsigned char) **type)) 511169695Skan (*type)++; 512169695Skan return -1; 513169695Skan } 514169695Skan 515169695Skan count += **type - '0'; 516169695Skan (*type)++; 517169695Skan } 518169695Skan 519169695Skan if (count < 0) 520169695Skan count = -1; 521169695Skan 522169695Skan return (count); 523169695Skan} 524169695Skan 525169695Skan 526169695Skan/* Like consume_count, but for counts that are preceded and followed 527169695Skan by '_' if they are greater than 10. Also, -1 is returned for 528169695Skan failure, since 0 can be a valid value. */ 529169695Skan 530169695Skanstatic int 531169695Skanconsume_count_with_underscores (const char **mangled) 532169695Skan{ 533169695Skan int idx; 534169695Skan 535169695Skan if (**mangled == '_') 536169695Skan { 537169695Skan (*mangled)++; 538169695Skan if (!ISDIGIT ((unsigned char)**mangled)) 539169695Skan return -1; 540169695Skan 541169695Skan idx = consume_count (mangled); 542169695Skan if (**mangled != '_') 543169695Skan /* The trailing underscore was missing. */ 544169695Skan return -1; 545169695Skan 546169695Skan (*mangled)++; 547169695Skan } 548169695Skan else 549169695Skan { 550169695Skan if (**mangled < '0' || **mangled > '9') 551169695Skan return -1; 552169695Skan 553169695Skan idx = **mangled - '0'; 554169695Skan (*mangled)++; 555169695Skan } 556169695Skan 557169695Skan return idx; 558169695Skan} 559169695Skan 560169695Skan/* C is the code for a type-qualifier. Return the TYPE_QUAL 561169695Skan corresponding to this qualifier. */ 562169695Skan 563169695Skanstatic int 564169695Skancode_for_qualifier (int c) 565169695Skan{ 566169695Skan switch (c) 567169695Skan { 568169695Skan case 'C': 569169695Skan return TYPE_QUAL_CONST; 570169695Skan 571169695Skan case 'V': 572169695Skan return TYPE_QUAL_VOLATILE; 573169695Skan 574169695Skan case 'u': 575169695Skan return TYPE_QUAL_RESTRICT; 576169695Skan 577169695Skan default: 578169695Skan break; 579169695Skan } 580169695Skan 581169695Skan /* C was an invalid qualifier. */ 582169695Skan abort (); 583169695Skan} 584169695Skan 585169695Skan/* Return the string corresponding to the qualifiers given by 586169695Skan TYPE_QUALS. */ 587169695Skan 588169695Skanstatic const char* 589169695Skanqualifier_string (int type_quals) 590169695Skan{ 591169695Skan switch (type_quals) 592169695Skan { 593169695Skan case TYPE_UNQUALIFIED: 594169695Skan return ""; 595169695Skan 596169695Skan case TYPE_QUAL_CONST: 597169695Skan return "const"; 598169695Skan 599169695Skan case TYPE_QUAL_VOLATILE: 600169695Skan return "volatile"; 601169695Skan 602169695Skan case TYPE_QUAL_RESTRICT: 603169695Skan return "__restrict"; 604169695Skan 605169695Skan case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE: 606169695Skan return "const volatile"; 607169695Skan 608169695Skan case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT: 609169695Skan return "const __restrict"; 610169695Skan 611169695Skan case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: 612169695Skan return "volatile __restrict"; 613169695Skan 614169695Skan case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: 615169695Skan return "const volatile __restrict"; 616169695Skan 617169695Skan default: 618169695Skan break; 619169695Skan } 620169695Skan 621169695Skan /* TYPE_QUALS was an invalid qualifier set. */ 622169695Skan abort (); 623169695Skan} 624169695Skan 625169695Skan/* C is the code for a type-qualifier. Return the string 626169695Skan corresponding to this qualifier. This function should only be 627169695Skan called with a valid qualifier code. */ 628169695Skan 629169695Skanstatic const char* 630169695Skandemangle_qualifier (int c) 631169695Skan{ 632169695Skan return qualifier_string (code_for_qualifier (c)); 633169695Skan} 634169695Skan 635169695Skanint 636169695Skancplus_demangle_opname (const char *opname, char *result, int options) 637169695Skan{ 638169695Skan int len, len1, ret; 639169695Skan string type; 640169695Skan struct work_stuff work[1]; 641169695Skan const char *tem; 642169695Skan 643169695Skan len = strlen(opname); 644169695Skan result[0] = '\0'; 645169695Skan ret = 0; 646169695Skan memset ((char *) work, 0, sizeof (work)); 647169695Skan work->options = options; 648169695Skan 649169695Skan if (opname[0] == '_' && opname[1] == '_' 650169695Skan && opname[2] == 'o' && opname[3] == 'p') 651169695Skan { 652169695Skan /* ANSI. */ 653169695Skan /* type conversion operator. */ 654169695Skan tem = opname + 4; 655169695Skan if (do_type (work, &tem, &type)) 656169695Skan { 657169695Skan strcat (result, "operator "); 658169695Skan strncat (result, type.b, type.p - type.b); 659169695Skan string_delete (&type); 660169695Skan ret = 1; 661169695Skan } 662169695Skan } 663169695Skan else if (opname[0] == '_' && opname[1] == '_' 664169695Skan && ISLOWER((unsigned char)opname[2]) 665169695Skan && ISLOWER((unsigned char)opname[3])) 666169695Skan { 667169695Skan if (opname[4] == '\0') 668169695Skan { 669169695Skan /* Operator. */ 670169695Skan size_t i; 671169695Skan for (i = 0; i < ARRAY_SIZE (optable); i++) 672169695Skan { 673169695Skan if (strlen (optable[i].in) == 2 674169695Skan && memcmp (optable[i].in, opname + 2, 2) == 0) 675169695Skan { 676169695Skan strcat (result, "operator"); 677169695Skan strcat (result, optable[i].out); 678169695Skan ret = 1; 679169695Skan break; 680169695Skan } 681169695Skan } 682169695Skan } 683169695Skan else 684169695Skan { 685169695Skan if (opname[2] == 'a' && opname[5] == '\0') 686169695Skan { 687169695Skan /* Assignment. */ 688169695Skan size_t i; 689169695Skan for (i = 0; i < ARRAY_SIZE (optable); i++) 690169695Skan { 691169695Skan if (strlen (optable[i].in) == 3 692169695Skan && memcmp (optable[i].in, opname + 2, 3) == 0) 693169695Skan { 694169695Skan strcat (result, "operator"); 695169695Skan strcat (result, optable[i].out); 696169695Skan ret = 1; 697169695Skan break; 698169695Skan } 699169695Skan } 700169695Skan } 701169695Skan } 702169695Skan } 703169695Skan else if (len >= 3 704169695Skan && opname[0] == 'o' 705169695Skan && opname[1] == 'p' 706169695Skan && strchr (cplus_markers, opname[2]) != NULL) 707169695Skan { 708169695Skan /* see if it's an assignment expression */ 709169695Skan if (len >= 10 /* op$assign_ */ 710169695Skan && memcmp (opname + 3, "assign_", 7) == 0) 711169695Skan { 712169695Skan size_t i; 713169695Skan for (i = 0; i < ARRAY_SIZE (optable); i++) 714169695Skan { 715169695Skan len1 = len - 10; 716169695Skan if ((int) strlen (optable[i].in) == len1 717169695Skan && memcmp (optable[i].in, opname + 10, len1) == 0) 718169695Skan { 719169695Skan strcat (result, "operator"); 720169695Skan strcat (result, optable[i].out); 721169695Skan strcat (result, "="); 722169695Skan ret = 1; 723169695Skan break; 724169695Skan } 725169695Skan } 726169695Skan } 727169695Skan else 728169695Skan { 729169695Skan size_t i; 730169695Skan for (i = 0; i < ARRAY_SIZE (optable); i++) 731169695Skan { 732169695Skan len1 = len - 3; 733169695Skan if ((int) strlen (optable[i].in) == len1 734169695Skan && memcmp (optable[i].in, opname + 3, len1) == 0) 735169695Skan { 736169695Skan strcat (result, "operator"); 737169695Skan strcat (result, optable[i].out); 738169695Skan ret = 1; 739169695Skan break; 740169695Skan } 741169695Skan } 742169695Skan } 743169695Skan } 744169695Skan else if (len >= 5 && memcmp (opname, "type", 4) == 0 745169695Skan && strchr (cplus_markers, opname[4]) != NULL) 746169695Skan { 747169695Skan /* type conversion operator */ 748169695Skan tem = opname + 5; 749169695Skan if (do_type (work, &tem, &type)) 750169695Skan { 751169695Skan strcat (result, "operator "); 752169695Skan strncat (result, type.b, type.p - type.b); 753169695Skan string_delete (&type); 754169695Skan ret = 1; 755169695Skan } 756169695Skan } 757169695Skan squangle_mop_up (work); 758169695Skan return ret; 759169695Skan 760169695Skan} 761169695Skan 762169695Skan/* Takes operator name as e.g. "++" and returns mangled 763169695Skan operator name (e.g. "postincrement_expr"), or NULL if not found. 764169695Skan 765169695Skan If OPTIONS & DMGL_ANSI == 1, return the ANSI name; 766169695Skan if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */ 767169695Skan 768169695Skanconst char * 769169695Skancplus_mangle_opname (const char *opname, int options) 770169695Skan{ 771169695Skan size_t i; 772169695Skan int len; 773169695Skan 774169695Skan len = strlen (opname); 775169695Skan for (i = 0; i < ARRAY_SIZE (optable); i++) 776169695Skan { 777169695Skan if ((int) strlen (optable[i].out) == len 778169695Skan && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI) 779169695Skan && memcmp (optable[i].out, opname, len) == 0) 780169695Skan return optable[i].in; 781169695Skan } 782169695Skan return (0); 783169695Skan} 784169695Skan 785169695Skan/* Add a routine to set the demangling style to be sure it is valid and 786169695Skan allow for any demangler initialization that maybe necessary. */ 787169695Skan 788169695Skanenum demangling_styles 789169695Skancplus_demangle_set_style (enum demangling_styles style) 790169695Skan{ 791169695Skan const struct demangler_engine *demangler = libiberty_demanglers; 792169695Skan 793169695Skan for (; demangler->demangling_style != unknown_demangling; ++demangler) 794169695Skan if (style == demangler->demangling_style) 795169695Skan { 796169695Skan current_demangling_style = style; 797169695Skan return current_demangling_style; 798169695Skan } 799169695Skan 800169695Skan return unknown_demangling; 801169695Skan} 802169695Skan 803169695Skan/* Do string name to style translation */ 804169695Skan 805169695Skanenum demangling_styles 806169695Skancplus_demangle_name_to_style (const char *name) 807169695Skan{ 808169695Skan const struct demangler_engine *demangler = libiberty_demanglers; 809169695Skan 810169695Skan for (; demangler->demangling_style != unknown_demangling; ++demangler) 811169695Skan if (strcmp (name, demangler->demangling_style_name) == 0) 812169695Skan return demangler->demangling_style; 813169695Skan 814169695Skan return unknown_demangling; 815169695Skan} 816169695Skan 817169695Skan/* char *cplus_demangle (const char *mangled, int options) 818169695Skan 819169695Skan If MANGLED is a mangled function name produced by GNU C++, then 820169695Skan a pointer to a @code{malloc}ed string giving a C++ representation 821169695Skan of the name will be returned; otherwise NULL will be returned. 822169695Skan It is the caller's responsibility to free the string which 823169695Skan is returned. 824169695Skan 825169695Skan The OPTIONS arg may contain one or more of the following bits: 826169695Skan 827169695Skan DMGL_ANSI ANSI qualifiers such as `const' and `void' are 828169695Skan included. 829169695Skan DMGL_PARAMS Function parameters are included. 830169695Skan 831169695Skan For example, 832169695Skan 833169695Skan cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)" 834169695Skan cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)" 835169695Skan cplus_demangle ("foo__1Ai", 0) => "A::foo" 836169695Skan 837169695Skan cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)" 838169695Skan cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)" 839169695Skan cplus_demangle ("foo__1Afe", 0) => "A::foo" 840169695Skan 841169695Skan Note that any leading underscores, or other such characters prepended by 842169695Skan the compilation system, are presumed to have already been stripped from 843169695Skan MANGLED. */ 844169695Skan 845169695Skanchar * 846169695Skancplus_demangle (const char *mangled, int options) 847169695Skan{ 848169695Skan char *ret; 849169695Skan struct work_stuff work[1]; 850169695Skan 851169695Skan if (current_demangling_style == no_demangling) 852169695Skan return xstrdup (mangled); 853169695Skan 854169695Skan memset ((char *) work, 0, sizeof (work)); 855169695Skan work->options = options; 856169695Skan if ((work->options & DMGL_STYLE_MASK) == 0) 857169695Skan work->options |= (int) current_demangling_style & DMGL_STYLE_MASK; 858169695Skan 859169695Skan /* The V3 ABI demangling is implemented elsewhere. */ 860169695Skan if (GNU_V3_DEMANGLING || AUTO_DEMANGLING) 861169695Skan { 862169695Skan ret = cplus_demangle_v3 (mangled, work->options); 863169695Skan if (ret || GNU_V3_DEMANGLING) 864169695Skan return ret; 865169695Skan } 866169695Skan 867169695Skan if (JAVA_DEMANGLING) 868169695Skan { 869169695Skan ret = java_demangle_v3 (mangled); 870169695Skan if (ret) 871169695Skan return ret; 872169695Skan } 873169695Skan 874169695Skan if (GNAT_DEMANGLING) 875169695Skan return ada_demangle(mangled,options); 876169695Skan 877169695Skan ret = internal_cplus_demangle (work, mangled); 878169695Skan squangle_mop_up (work); 879169695Skan return (ret); 880169695Skan} 881169695Skan 882169695Skan 883169695Skan/* Assuming *OLD_VECT points to an array of *SIZE objects of size 884169695Skan ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects, 885169695Skan updating *OLD_VECT and *SIZE as necessary. */ 886169695Skan 887169695Skanstatic void 888169695Skangrow_vect (char **old_vect, size_t *size, size_t min_size, int element_size) 889169695Skan{ 890169695Skan if (*size < min_size) 891169695Skan { 892169695Skan *size *= 2; 893169695Skan if (*size < min_size) 894169695Skan *size = min_size; 895169695Skan *old_vect = XRESIZEVAR (char, *old_vect, *size * element_size); 896169695Skan } 897169695Skan} 898169695Skan 899169695Skan/* Demangle ada names: 900169695Skan 1. Discard final __{DIGIT}+ or ${DIGIT}+ 901169695Skan 2. Convert other instances of embedded "__" to `.'. 902169695Skan 3. Discard leading _ada_. 903169695Skan 4. Remove everything after first ___ if it is followed by 'X'. 904169695Skan 5. Put symbols that should be suppressed in <...> brackets. 905169695Skan The resulting string is valid until the next call of ada_demangle. */ 906169695Skan 907169695Skanstatic char * 908169695Skanada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED) 909169695Skan{ 910169695Skan int i, j; 911169695Skan int len0; 912169695Skan const char* p; 913169695Skan char *demangled = NULL; 914169695Skan int changed; 915169695Skan size_t demangled_size = 0; 916169695Skan 917169695Skan changed = 0; 918169695Skan 919169695Skan if (strncmp (mangled, "_ada_", 5) == 0) 920169695Skan { 921169695Skan mangled += 5; 922169695Skan changed = 1; 923169695Skan } 924169695Skan 925169695Skan if (mangled[0] == '_' || mangled[0] == '<') 926169695Skan goto Suppress; 927169695Skan 928169695Skan p = strstr (mangled, "___"); 929169695Skan if (p == NULL) 930169695Skan len0 = strlen (mangled); 931169695Skan else 932169695Skan { 933169695Skan if (p[3] == 'X') 934169695Skan { 935169695Skan len0 = p - mangled; 936169695Skan changed = 1; 937169695Skan } 938169695Skan else 939169695Skan goto Suppress; 940169695Skan } 941169695Skan 942169695Skan /* Make demangled big enough for possible expansion by operator name. */ 943169695Skan grow_vect (&demangled, 944169695Skan &demangled_size, 2 * len0 + 1, 945169695Skan sizeof (char)); 946169695Skan 947169695Skan if (ISDIGIT ((unsigned char) mangled[len0 - 1])) { 948169695Skan for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1) 949169695Skan ; 950169695Skan if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_') 951169695Skan { 952169695Skan len0 = i - 1; 953169695Skan changed = 1; 954169695Skan } 955169695Skan else if (mangled[i] == '$') 956169695Skan { 957169695Skan len0 = i; 958169695Skan changed = 1; 959169695Skan } 960169695Skan } 961169695Skan 962169695Skan for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]); 963169695Skan i += 1, j += 1) 964169695Skan demangled[j] = mangled[i]; 965169695Skan 966169695Skan while (i < len0) 967169695Skan { 968169695Skan if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_') 969169695Skan { 970169695Skan demangled[j] = '.'; 971169695Skan changed = 1; 972169695Skan i += 2; j += 1; 973169695Skan } 974169695Skan else 975169695Skan { 976169695Skan demangled[j] = mangled[i]; 977169695Skan i += 1; j += 1; 978169695Skan } 979169695Skan } 980169695Skan demangled[j] = '\000'; 981169695Skan 982169695Skan for (i = 0; demangled[i] != '\0'; i += 1) 983169695Skan if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ') 984169695Skan goto Suppress; 985169695Skan 986169695Skan if (! changed) 987169695Skan return NULL; 988169695Skan else 989169695Skan return demangled; 990169695Skan 991169695Skan Suppress: 992169695Skan grow_vect (&demangled, 993169695Skan &demangled_size, strlen (mangled) + 3, 994169695Skan sizeof (char)); 995169695Skan 996169695Skan if (mangled[0] == '<') 997169695Skan strcpy (demangled, mangled); 998169695Skan else 999169695Skan sprintf (demangled, "<%s>", mangled); 1000169695Skan 1001169695Skan return demangled; 1002169695Skan} 1003169695Skan 1004169695Skan/* This function performs most of what cplus_demangle use to do, but 1005169695Skan to be able to demangle a name with a B, K or n code, we need to 1006169695Skan have a longer term memory of what types have been seen. The original 1007169695Skan now initializes and cleans up the squangle code info, while internal 1008169695Skan calls go directly to this routine to avoid resetting that info. */ 1009169695Skan 1010169695Skanstatic char * 1011169695Skaninternal_cplus_demangle (struct work_stuff *work, const char *mangled) 1012169695Skan{ 1013169695Skan 1014169695Skan string decl; 1015169695Skan int success = 0; 1016169695Skan char *demangled = NULL; 1017169695Skan int s1, s2, s3, s4; 1018169695Skan s1 = work->constructor; 1019169695Skan s2 = work->destructor; 1020169695Skan s3 = work->static_type; 1021169695Skan s4 = work->type_quals; 1022169695Skan work->constructor = work->destructor = 0; 1023169695Skan work->type_quals = TYPE_UNQUALIFIED; 1024169695Skan work->dllimported = 0; 1025169695Skan 1026169695Skan if ((mangled != NULL) && (*mangled != '\0')) 1027169695Skan { 1028169695Skan string_init (&decl); 1029169695Skan 1030169695Skan /* First check to see if gnu style demangling is active and if the 1031169695Skan string to be demangled contains a CPLUS_MARKER. If so, attempt to 1032169695Skan recognize one of the gnu special forms rather than looking for a 1033169695Skan standard prefix. In particular, don't worry about whether there 1034169695Skan is a "__" string in the mangled string. Consider "_$_5__foo" for 1035169695Skan example. */ 1036169695Skan 1037169695Skan if ((AUTO_DEMANGLING || GNU_DEMANGLING)) 1038169695Skan { 1039169695Skan success = gnu_special (work, &mangled, &decl); 1040169695Skan } 1041169695Skan if (!success) 1042169695Skan { 1043169695Skan success = demangle_prefix (work, &mangled, &decl); 1044169695Skan } 1045169695Skan if (success && (*mangled != '\0')) 1046169695Skan { 1047169695Skan success = demangle_signature (work, &mangled, &decl); 1048169695Skan } 1049169695Skan if (work->constructor == 2) 1050169695Skan { 1051169695Skan string_prepend (&decl, "global constructors keyed to "); 1052169695Skan work->constructor = 0; 1053169695Skan } 1054169695Skan else if (work->destructor == 2) 1055169695Skan { 1056169695Skan string_prepend (&decl, "global destructors keyed to "); 1057169695Skan work->destructor = 0; 1058169695Skan } 1059169695Skan else if (work->dllimported == 1) 1060169695Skan { 1061169695Skan string_prepend (&decl, "import stub for "); 1062169695Skan work->dllimported = 0; 1063169695Skan } 1064169695Skan demangled = mop_up (work, &decl, success); 1065169695Skan } 1066169695Skan work->constructor = s1; 1067169695Skan work->destructor = s2; 1068169695Skan work->static_type = s3; 1069169695Skan work->type_quals = s4; 1070169695Skan return demangled; 1071169695Skan} 1072169695Skan 1073169695Skan 1074169695Skan/* Clear out and squangling related storage */ 1075169695Skanstatic void 1076169695Skansquangle_mop_up (struct work_stuff *work) 1077169695Skan{ 1078169695Skan /* clean up the B and K type mangling types. */ 1079169695Skan forget_B_and_K_types (work); 1080169695Skan if (work -> btypevec != NULL) 1081169695Skan { 1082169695Skan free ((char *) work -> btypevec); 1083169695Skan } 1084169695Skan if (work -> ktypevec != NULL) 1085169695Skan { 1086169695Skan free ((char *) work -> ktypevec); 1087169695Skan } 1088169695Skan} 1089169695Skan 1090169695Skan 1091169695Skan/* Copy the work state and storage. */ 1092169695Skan 1093169695Skanstatic void 1094169695Skanwork_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from) 1095169695Skan{ 1096169695Skan int i; 1097169695Skan 1098169695Skan delete_work_stuff (to); 1099169695Skan 1100169695Skan /* Shallow-copy scalars. */ 1101169695Skan memcpy (to, from, sizeof (*to)); 1102169695Skan 1103169695Skan /* Deep-copy dynamic storage. */ 1104169695Skan if (from->typevec_size) 1105169695Skan to->typevec = XNEWVEC (char *, from->typevec_size); 1106169695Skan 1107169695Skan for (i = 0; i < from->ntypes; i++) 1108169695Skan { 1109169695Skan int len = strlen (from->typevec[i]) + 1; 1110169695Skan 1111169695Skan to->typevec[i] = XNEWVEC (char, len); 1112169695Skan memcpy (to->typevec[i], from->typevec[i], len); 1113169695Skan } 1114169695Skan 1115169695Skan if (from->ksize) 1116169695Skan to->ktypevec = XNEWVEC (char *, from->ksize); 1117169695Skan 1118169695Skan for (i = 0; i < from->numk; i++) 1119169695Skan { 1120169695Skan int len = strlen (from->ktypevec[i]) + 1; 1121169695Skan 1122169695Skan to->ktypevec[i] = XNEWVEC (char, len); 1123169695Skan memcpy (to->ktypevec[i], from->ktypevec[i], len); 1124169695Skan } 1125169695Skan 1126169695Skan if (from->bsize) 1127169695Skan to->btypevec = XNEWVEC (char *, from->bsize); 1128169695Skan 1129169695Skan for (i = 0; i < from->numb; i++) 1130169695Skan { 1131169695Skan int len = strlen (from->btypevec[i]) + 1; 1132169695Skan 1133169695Skan to->btypevec[i] = XNEWVEC (char , len); 1134169695Skan memcpy (to->btypevec[i], from->btypevec[i], len); 1135169695Skan } 1136169695Skan 1137169695Skan if (from->ntmpl_args) 1138169695Skan to->tmpl_argvec = XNEWVEC (char *, from->ntmpl_args); 1139169695Skan 1140169695Skan for (i = 0; i < from->ntmpl_args; i++) 1141169695Skan { 1142169695Skan int len = strlen (from->tmpl_argvec[i]) + 1; 1143169695Skan 1144169695Skan to->tmpl_argvec[i] = XNEWVEC (char, len); 1145169695Skan memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len); 1146169695Skan } 1147169695Skan 1148169695Skan if (from->previous_argument) 1149169695Skan { 1150169695Skan to->previous_argument = XNEW (string); 1151169695Skan string_init (to->previous_argument); 1152169695Skan string_appends (to->previous_argument, from->previous_argument); 1153169695Skan } 1154169695Skan} 1155169695Skan 1156169695Skan 1157169695Skan/* Delete dynamic stuff in work_stuff that is not to be re-used. */ 1158169695Skan 1159169695Skanstatic void 1160169695Skandelete_non_B_K_work_stuff (struct work_stuff *work) 1161169695Skan{ 1162169695Skan /* Discard the remembered types, if any. */ 1163169695Skan 1164169695Skan forget_types (work); 1165169695Skan if (work -> typevec != NULL) 1166169695Skan { 1167169695Skan free ((char *) work -> typevec); 1168169695Skan work -> typevec = NULL; 1169169695Skan work -> typevec_size = 0; 1170169695Skan } 1171169695Skan if (work->tmpl_argvec) 1172169695Skan { 1173169695Skan int i; 1174169695Skan 1175169695Skan for (i = 0; i < work->ntmpl_args; i++) 1176169695Skan if (work->tmpl_argvec[i]) 1177169695Skan free ((char*) work->tmpl_argvec[i]); 1178169695Skan 1179169695Skan free ((char*) work->tmpl_argvec); 1180169695Skan work->tmpl_argvec = NULL; 1181169695Skan } 1182169695Skan if (work->previous_argument) 1183169695Skan { 1184169695Skan string_delete (work->previous_argument); 1185169695Skan free ((char*) work->previous_argument); 1186169695Skan work->previous_argument = NULL; 1187169695Skan } 1188169695Skan} 1189169695Skan 1190169695Skan 1191169695Skan/* Delete all dynamic storage in work_stuff. */ 1192169695Skanstatic void 1193169695Skandelete_work_stuff (struct work_stuff *work) 1194169695Skan{ 1195169695Skan delete_non_B_K_work_stuff (work); 1196169695Skan squangle_mop_up (work); 1197169695Skan} 1198169695Skan 1199169695Skan 1200169695Skan/* Clear out any mangled storage */ 1201169695Skan 1202169695Skanstatic char * 1203169695Skanmop_up (struct work_stuff *work, string *declp, int success) 1204169695Skan{ 1205169695Skan char *demangled = NULL; 1206169695Skan 1207169695Skan delete_non_B_K_work_stuff (work); 1208169695Skan 1209169695Skan /* If demangling was successful, ensure that the demangled string is null 1210169695Skan terminated and return it. Otherwise, free the demangling decl. */ 1211169695Skan 1212169695Skan if (!success) 1213169695Skan { 1214169695Skan string_delete (declp); 1215169695Skan } 1216169695Skan else 1217169695Skan { 1218169695Skan string_appendn (declp, "", 1); 1219169695Skan demangled = declp->b; 1220169695Skan } 1221169695Skan return (demangled); 1222169695Skan} 1223169695Skan 1224169695Skan/* 1225169695Skan 1226169695SkanLOCAL FUNCTION 1227169695Skan 1228169695Skan demangle_signature -- demangle the signature part of a mangled name 1229169695Skan 1230169695SkanSYNOPSIS 1231169695Skan 1232169695Skan static int 1233169695Skan demangle_signature (struct work_stuff *work, const char **mangled, 1234169695Skan string *declp); 1235169695Skan 1236169695SkanDESCRIPTION 1237169695Skan 1238169695Skan Consume and demangle the signature portion of the mangled name. 1239169695Skan 1240169695Skan DECLP is the string where demangled output is being built. At 1241169695Skan entry it contains the demangled root name from the mangled name 1242169695Skan prefix. I.E. either a demangled operator name or the root function 1243169695Skan name. In some special cases, it may contain nothing. 1244169695Skan 1245169695Skan *MANGLED points to the current unconsumed location in the mangled 1246169695Skan name. As tokens are consumed and demangling is performed, the 1247169695Skan pointer is updated to continuously point at the next token to 1248169695Skan be consumed. 1249169695Skan 1250169695Skan Demangling GNU style mangled names is nasty because there is no 1251169695Skan explicit token that marks the start of the outermost function 1252169695Skan argument list. */ 1253169695Skan 1254169695Skanstatic int 1255169695Skandemangle_signature (struct work_stuff *work, 1256169695Skan const char **mangled, string *declp) 1257169695Skan{ 1258169695Skan int success = 1; 1259169695Skan int func_done = 0; 1260169695Skan int expect_func = 0; 1261169695Skan int expect_return_type = 0; 1262169695Skan const char *oldmangled = NULL; 1263169695Skan string trawname; 1264169695Skan string tname; 1265169695Skan 1266169695Skan while (success && (**mangled != '\0')) 1267169695Skan { 1268169695Skan switch (**mangled) 1269169695Skan { 1270169695Skan case 'Q': 1271169695Skan oldmangled = *mangled; 1272169695Skan success = demangle_qualified (work, mangled, declp, 1, 0); 1273169695Skan if (success) 1274169695Skan remember_type (work, oldmangled, *mangled - oldmangled); 1275169695Skan if (AUTO_DEMANGLING || GNU_DEMANGLING) 1276169695Skan expect_func = 1; 1277169695Skan oldmangled = NULL; 1278169695Skan break; 1279169695Skan 1280169695Skan case 'K': 1281169695Skan oldmangled = *mangled; 1282169695Skan success = demangle_qualified (work, mangled, declp, 1, 0); 1283169695Skan if (AUTO_DEMANGLING || GNU_DEMANGLING) 1284169695Skan { 1285169695Skan expect_func = 1; 1286169695Skan } 1287169695Skan oldmangled = NULL; 1288169695Skan break; 1289169695Skan 1290169695Skan case 'S': 1291169695Skan /* Static member function */ 1292169695Skan if (oldmangled == NULL) 1293169695Skan { 1294169695Skan oldmangled = *mangled; 1295169695Skan } 1296169695Skan (*mangled)++; 1297169695Skan work -> static_type = 1; 1298169695Skan break; 1299169695Skan 1300169695Skan case 'C': 1301169695Skan case 'V': 1302169695Skan case 'u': 1303169695Skan work->type_quals |= code_for_qualifier (**mangled); 1304169695Skan 1305169695Skan /* a qualified member function */ 1306169695Skan if (oldmangled == NULL) 1307169695Skan oldmangled = *mangled; 1308169695Skan (*mangled)++; 1309169695Skan break; 1310169695Skan 1311169695Skan case 'L': 1312169695Skan /* Local class name follows after "Lnnn_" */ 1313169695Skan if (HP_DEMANGLING) 1314169695Skan { 1315169695Skan while (**mangled && (**mangled != '_')) 1316169695Skan (*mangled)++; 1317169695Skan if (!**mangled) 1318169695Skan success = 0; 1319169695Skan else 1320169695Skan (*mangled)++; 1321169695Skan } 1322169695Skan else 1323169695Skan success = 0; 1324169695Skan break; 1325169695Skan 1326169695Skan case '0': case '1': case '2': case '3': case '4': 1327169695Skan case '5': case '6': case '7': case '8': case '9': 1328169695Skan if (oldmangled == NULL) 1329169695Skan { 1330169695Skan oldmangled = *mangled; 1331169695Skan } 1332169695Skan work->temp_start = -1; /* uppermost call to demangle_class */ 1333169695Skan success = demangle_class (work, mangled, declp); 1334169695Skan if (success) 1335169695Skan { 1336169695Skan remember_type (work, oldmangled, *mangled - oldmangled); 1337169695Skan } 1338169695Skan if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING) 1339169695Skan { 1340169695Skan /* EDG and others will have the "F", so we let the loop cycle 1341169695Skan if we are looking at one. */ 1342169695Skan if (**mangled != 'F') 1343169695Skan expect_func = 1; 1344169695Skan } 1345169695Skan oldmangled = NULL; 1346169695Skan break; 1347169695Skan 1348169695Skan case 'B': 1349169695Skan { 1350169695Skan string s; 1351169695Skan success = do_type (work, mangled, &s); 1352169695Skan if (success) 1353169695Skan { 1354169695Skan string_append (&s, SCOPE_STRING (work)); 1355169695Skan string_prepends (declp, &s); 1356169695Skan string_delete (&s); 1357169695Skan } 1358169695Skan oldmangled = NULL; 1359169695Skan expect_func = 1; 1360169695Skan } 1361169695Skan break; 1362169695Skan 1363169695Skan case 'F': 1364169695Skan /* Function */ 1365169695Skan /* ARM/HP style demangling includes a specific 'F' character after 1366169695Skan the class name. For GNU style, it is just implied. So we can 1367169695Skan safely just consume any 'F' at this point and be compatible 1368169695Skan with either style. */ 1369169695Skan 1370169695Skan oldmangled = NULL; 1371169695Skan func_done = 1; 1372169695Skan (*mangled)++; 1373169695Skan 1374169695Skan /* For lucid/ARM/HP style we have to forget any types we might 1375169695Skan have remembered up to this point, since they were not argument 1376169695Skan types. GNU style considers all types seen as available for 1377169695Skan back references. See comment in demangle_args() */ 1378169695Skan 1379169695Skan if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) 1380169695Skan { 1381169695Skan forget_types (work); 1382169695Skan } 1383169695Skan success = demangle_args (work, mangled, declp); 1384169695Skan /* After picking off the function args, we expect to either 1385169695Skan find the function return type (preceded by an '_') or the 1386169695Skan end of the string. */ 1387169695Skan if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_') 1388169695Skan { 1389169695Skan ++(*mangled); 1390169695Skan /* At this level, we do not care about the return type. */ 1391169695Skan success = do_type (work, mangled, &tname); 1392169695Skan string_delete (&tname); 1393169695Skan } 1394169695Skan 1395169695Skan break; 1396169695Skan 1397169695Skan case 't': 1398169695Skan /* G++ Template */ 1399169695Skan string_init(&trawname); 1400169695Skan string_init(&tname); 1401169695Skan if (oldmangled == NULL) 1402169695Skan { 1403169695Skan oldmangled = *mangled; 1404169695Skan } 1405169695Skan success = demangle_template (work, mangled, &tname, 1406169695Skan &trawname, 1, 1); 1407169695Skan if (success) 1408169695Skan { 1409169695Skan remember_type (work, oldmangled, *mangled - oldmangled); 1410169695Skan } 1411169695Skan string_append (&tname, SCOPE_STRING (work)); 1412169695Skan 1413169695Skan string_prepends(declp, &tname); 1414169695Skan if (work -> destructor & 1) 1415169695Skan { 1416169695Skan string_prepend (&trawname, "~"); 1417169695Skan string_appends (declp, &trawname); 1418169695Skan work->destructor -= 1; 1419169695Skan } 1420169695Skan if ((work->constructor & 1) || (work->destructor & 1)) 1421169695Skan { 1422169695Skan string_appends (declp, &trawname); 1423169695Skan work->constructor -= 1; 1424169695Skan } 1425169695Skan string_delete(&trawname); 1426169695Skan string_delete(&tname); 1427169695Skan oldmangled = NULL; 1428169695Skan expect_func = 1; 1429169695Skan break; 1430169695Skan 1431169695Skan case '_': 1432169695Skan if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type) 1433169695Skan { 1434169695Skan /* Read the return type. */ 1435169695Skan string return_type; 1436169695Skan 1437169695Skan (*mangled)++; 1438169695Skan success = do_type (work, mangled, &return_type); 1439169695Skan APPEND_BLANK (&return_type); 1440169695Skan 1441169695Skan string_prepends (declp, &return_type); 1442169695Skan string_delete (&return_type); 1443169695Skan break; 1444169695Skan } 1445169695Skan else 1446169695Skan /* At the outermost level, we cannot have a return type specified, 1447169695Skan so if we run into another '_' at this point we are dealing with 1448169695Skan a mangled name that is either bogus, or has been mangled by 1449169695Skan some algorithm we don't know how to deal with. So just 1450169695Skan reject the entire demangling. */ 1451169695Skan /* However, "_nnn" is an expected suffix for alternate entry point 1452169695Skan numbered nnn for a function, with HP aCC, so skip over that 1453169695Skan without reporting failure. pai/1997-09-04 */ 1454169695Skan if (HP_DEMANGLING) 1455169695Skan { 1456169695Skan (*mangled)++; 1457169695Skan while (**mangled && ISDIGIT ((unsigned char)**mangled)) 1458169695Skan (*mangled)++; 1459169695Skan } 1460169695Skan else 1461169695Skan success = 0; 1462169695Skan break; 1463169695Skan 1464169695Skan case 'H': 1465169695Skan if (AUTO_DEMANGLING || GNU_DEMANGLING) 1466169695Skan { 1467169695Skan /* A G++ template function. Read the template arguments. */ 1468169695Skan success = demangle_template (work, mangled, declp, 0, 0, 1469169695Skan 0); 1470169695Skan if (!(work->constructor & 1)) 1471169695Skan expect_return_type = 1; 1472169695Skan (*mangled)++; 1473169695Skan break; 1474169695Skan } 1475169695Skan else 1476169695Skan /* fall through */ 1477169695Skan {;} 1478169695Skan 1479169695Skan default: 1480169695Skan if (AUTO_DEMANGLING || GNU_DEMANGLING) 1481169695Skan { 1482169695Skan /* Assume we have stumbled onto the first outermost function 1483169695Skan argument token, and start processing args. */ 1484169695Skan func_done = 1; 1485169695Skan success = demangle_args (work, mangled, declp); 1486169695Skan } 1487169695Skan else 1488169695Skan { 1489169695Skan /* Non-GNU demanglers use a specific token to mark the start 1490169695Skan of the outermost function argument tokens. Typically 'F', 1491169695Skan for ARM/HP-demangling, for example. So if we find something 1492169695Skan we are not prepared for, it must be an error. */ 1493169695Skan success = 0; 1494169695Skan } 1495169695Skan break; 1496169695Skan } 1497169695Skan /* 1498169695Skan if (AUTO_DEMANGLING || GNU_DEMANGLING) 1499169695Skan */ 1500169695Skan { 1501169695Skan if (success && expect_func) 1502169695Skan { 1503169695Skan func_done = 1; 1504169695Skan if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) 1505169695Skan { 1506169695Skan forget_types (work); 1507169695Skan } 1508169695Skan success = demangle_args (work, mangled, declp); 1509169695Skan /* Since template include the mangling of their return types, 1510169695Skan we must set expect_func to 0 so that we don't try do 1511169695Skan demangle more arguments the next time we get here. */ 1512169695Skan expect_func = 0; 1513169695Skan } 1514169695Skan } 1515169695Skan } 1516169695Skan if (success && !func_done) 1517169695Skan { 1518169695Skan if (AUTO_DEMANGLING || GNU_DEMANGLING) 1519169695Skan { 1520169695Skan /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and 1521169695Skan bar__3fooi is 'foo::bar(int)'. We get here when we find the 1522169695Skan first case, and need to ensure that the '(void)' gets added to 1523169695Skan the current declp. Note that with ARM/HP, the first case 1524169695Skan represents the name of a static data member 'foo::bar', 1525169695Skan which is in the current declp, so we leave it alone. */ 1526169695Skan success = demangle_args (work, mangled, declp); 1527169695Skan } 1528169695Skan } 1529169695Skan if (success && PRINT_ARG_TYPES) 1530169695Skan { 1531169695Skan if (work->static_type) 1532169695Skan string_append (declp, " static"); 1533169695Skan if (work->type_quals != TYPE_UNQUALIFIED) 1534169695Skan { 1535169695Skan APPEND_BLANK (declp); 1536169695Skan string_append (declp, qualifier_string (work->type_quals)); 1537169695Skan } 1538169695Skan } 1539169695Skan 1540169695Skan return (success); 1541169695Skan} 1542169695Skan 1543169695Skan#if 0 1544169695Skan 1545169695Skanstatic int 1546169695Skandemangle_method_args (struct work_stuff *work, const char **mangled, 1547169695Skan string *declp) 1548169695Skan{ 1549169695Skan int success = 0; 1550169695Skan 1551169695Skan if (work -> static_type) 1552169695Skan { 1553169695Skan string_append (declp, *mangled + 1); 1554169695Skan *mangled += strlen (*mangled); 1555169695Skan success = 1; 1556169695Skan } 1557169695Skan else 1558169695Skan { 1559169695Skan success = demangle_args (work, mangled, declp); 1560169695Skan } 1561169695Skan return (success); 1562169695Skan} 1563169695Skan 1564169695Skan#endif 1565169695Skan 1566169695Skanstatic int 1567169695Skandemangle_template_template_parm (struct work_stuff *work, 1568169695Skan const char **mangled, string *tname) 1569169695Skan{ 1570169695Skan int i; 1571169695Skan int r; 1572169695Skan int need_comma = 0; 1573169695Skan int success = 1; 1574169695Skan string temp; 1575169695Skan 1576169695Skan string_append (tname, "template <"); 1577169695Skan /* get size of template parameter list */ 1578169695Skan if (get_count (mangled, &r)) 1579169695Skan { 1580169695Skan for (i = 0; i < r; i++) 1581169695Skan { 1582169695Skan if (need_comma) 1583169695Skan { 1584169695Skan string_append (tname, ", "); 1585169695Skan } 1586169695Skan 1587169695Skan /* Z for type parameters */ 1588169695Skan if (**mangled == 'Z') 1589169695Skan { 1590169695Skan (*mangled)++; 1591169695Skan string_append (tname, "class"); 1592169695Skan } 1593169695Skan /* z for template parameters */ 1594169695Skan else if (**mangled == 'z') 1595169695Skan { 1596169695Skan (*mangled)++; 1597169695Skan success = 1598169695Skan demangle_template_template_parm (work, mangled, tname); 1599169695Skan if (!success) 1600169695Skan { 1601169695Skan break; 1602169695Skan } 1603169695Skan } 1604169695Skan else 1605169695Skan { 1606169695Skan /* temp is initialized in do_type */ 1607169695Skan success = do_type (work, mangled, &temp); 1608169695Skan if (success) 1609169695Skan { 1610169695Skan string_appends (tname, &temp); 1611169695Skan } 1612169695Skan string_delete(&temp); 1613169695Skan if (!success) 1614169695Skan { 1615169695Skan break; 1616169695Skan } 1617169695Skan } 1618169695Skan need_comma = 1; 1619169695Skan } 1620169695Skan 1621169695Skan } 1622169695Skan if (tname->p[-1] == '>') 1623169695Skan string_append (tname, " "); 1624169695Skan string_append (tname, "> class"); 1625169695Skan return (success); 1626169695Skan} 1627169695Skan 1628169695Skanstatic int 1629169695Skandemangle_expression (struct work_stuff *work, const char **mangled, 1630169695Skan string *s, type_kind_t tk) 1631169695Skan{ 1632169695Skan int need_operator = 0; 1633169695Skan int success; 1634169695Skan 1635169695Skan success = 1; 1636169695Skan string_appendn (s, "(", 1); 1637169695Skan (*mangled)++; 1638169695Skan while (success && **mangled != 'W' && **mangled != '\0') 1639169695Skan { 1640169695Skan if (need_operator) 1641169695Skan { 1642169695Skan size_t i; 1643169695Skan size_t len; 1644169695Skan 1645169695Skan success = 0; 1646169695Skan 1647169695Skan len = strlen (*mangled); 1648169695Skan 1649169695Skan for (i = 0; i < ARRAY_SIZE (optable); ++i) 1650169695Skan { 1651169695Skan size_t l = strlen (optable[i].in); 1652169695Skan 1653169695Skan if (l <= len 1654169695Skan && memcmp (optable[i].in, *mangled, l) == 0) 1655169695Skan { 1656169695Skan string_appendn (s, " ", 1); 1657169695Skan string_append (s, optable[i].out); 1658169695Skan string_appendn (s, " ", 1); 1659169695Skan success = 1; 1660169695Skan (*mangled) += l; 1661169695Skan break; 1662169695Skan } 1663169695Skan } 1664169695Skan 1665169695Skan if (!success) 1666169695Skan break; 1667169695Skan } 1668169695Skan else 1669169695Skan need_operator = 1; 1670169695Skan 1671169695Skan success = demangle_template_value_parm (work, mangled, s, tk); 1672169695Skan } 1673169695Skan 1674169695Skan if (**mangled != 'W') 1675169695Skan success = 0; 1676169695Skan else 1677169695Skan { 1678169695Skan string_appendn (s, ")", 1); 1679169695Skan (*mangled)++; 1680169695Skan } 1681169695Skan 1682169695Skan return success; 1683169695Skan} 1684169695Skan 1685169695Skanstatic int 1686169695Skandemangle_integral_value (struct work_stuff *work, 1687169695Skan const char **mangled, string *s) 1688169695Skan{ 1689169695Skan int success; 1690169695Skan 1691169695Skan if (**mangled == 'E') 1692169695Skan success = demangle_expression (work, mangled, s, tk_integral); 1693169695Skan else if (**mangled == 'Q' || **mangled == 'K') 1694169695Skan success = demangle_qualified (work, mangled, s, 0, 1); 1695169695Skan else 1696169695Skan { 1697169695Skan int value; 1698169695Skan 1699169695Skan /* By default, we let the number decide whether we shall consume an 1700169695Skan underscore. */ 1701169695Skan int multidigit_without_leading_underscore = 0; 1702169695Skan int leave_following_underscore = 0; 1703169695Skan 1704169695Skan success = 0; 1705169695Skan 1706169695Skan if (**mangled == '_') 1707169695Skan { 1708169695Skan if (mangled[0][1] == 'm') 1709169695Skan { 1710169695Skan /* Since consume_count_with_underscores does not handle the 1711169695Skan `m'-prefix we must do it here, using consume_count and 1712169695Skan adjusting underscores: we have to consume the underscore 1713169695Skan matching the prepended one. */ 1714169695Skan multidigit_without_leading_underscore = 1; 1715169695Skan string_appendn (s, "-", 1); 1716169695Skan (*mangled) += 2; 1717169695Skan } 1718169695Skan else 1719169695Skan { 1720169695Skan /* Do not consume a following underscore; 1721169695Skan consume_count_with_underscores will consume what 1722169695Skan should be consumed. */ 1723169695Skan leave_following_underscore = 1; 1724169695Skan } 1725169695Skan } 1726169695Skan else 1727169695Skan { 1728169695Skan /* Negative numbers are indicated with a leading `m'. */ 1729169695Skan if (**mangled == 'm') 1730169695Skan { 1731169695Skan string_appendn (s, "-", 1); 1732169695Skan (*mangled)++; 1733169695Skan } 1734169695Skan /* Since consume_count_with_underscores does not handle 1735169695Skan multi-digit numbers that do not start with an underscore, 1736169695Skan and this number can be an integer template parameter, 1737169695Skan we have to call consume_count. */ 1738169695Skan multidigit_without_leading_underscore = 1; 1739169695Skan /* These multi-digit numbers never end on an underscore, 1740169695Skan so if there is one then don't eat it. */ 1741169695Skan leave_following_underscore = 1; 1742169695Skan } 1743169695Skan 1744169695Skan /* We must call consume_count if we expect to remove a trailing 1745169695Skan underscore, since consume_count_with_underscores expects 1746169695Skan the leading underscore (that we consumed) if it is to handle 1747169695Skan multi-digit numbers. */ 1748169695Skan if (multidigit_without_leading_underscore) 1749169695Skan value = consume_count (mangled); 1750169695Skan else 1751169695Skan value = consume_count_with_underscores (mangled); 1752169695Skan 1753169695Skan if (value != -1) 1754169695Skan { 1755169695Skan char buf[INTBUF_SIZE]; 1756169695Skan sprintf (buf, "%d", value); 1757169695Skan string_append (s, buf); 1758169695Skan 1759169695Skan /* Numbers not otherwise delimited, might have an underscore 1760169695Skan appended as a delimeter, which we should skip. 1761169695Skan 1762169695Skan ??? This used to always remove a following underscore, which 1763169695Skan is wrong. If other (arbitrary) cases are followed by an 1764169695Skan underscore, we need to do something more radical. */ 1765169695Skan 1766169695Skan if ((value > 9 || multidigit_without_leading_underscore) 1767169695Skan && ! leave_following_underscore 1768169695Skan && **mangled == '_') 1769169695Skan (*mangled)++; 1770169695Skan 1771169695Skan /* All is well. */ 1772169695Skan success = 1; 1773169695Skan } 1774169695Skan } 1775169695Skan 1776169695Skan return success; 1777169695Skan} 1778169695Skan 1779169695Skan/* Demangle the real value in MANGLED. */ 1780169695Skan 1781169695Skanstatic int 1782169695Skandemangle_real_value (struct work_stuff *work, 1783169695Skan const char **mangled, string *s) 1784169695Skan{ 1785169695Skan if (**mangled == 'E') 1786169695Skan return demangle_expression (work, mangled, s, tk_real); 1787169695Skan 1788169695Skan if (**mangled == 'm') 1789169695Skan { 1790169695Skan string_appendn (s, "-", 1); 1791169695Skan (*mangled)++; 1792169695Skan } 1793169695Skan while (ISDIGIT ((unsigned char)**mangled)) 1794169695Skan { 1795169695Skan string_appendn (s, *mangled, 1); 1796169695Skan (*mangled)++; 1797169695Skan } 1798169695Skan if (**mangled == '.') /* fraction */ 1799169695Skan { 1800169695Skan string_appendn (s, ".", 1); 1801169695Skan (*mangled)++; 1802169695Skan while (ISDIGIT ((unsigned char)**mangled)) 1803169695Skan { 1804169695Skan string_appendn (s, *mangled, 1); 1805169695Skan (*mangled)++; 1806169695Skan } 1807169695Skan } 1808169695Skan if (**mangled == 'e') /* exponent */ 1809169695Skan { 1810169695Skan string_appendn (s, "e", 1); 1811169695Skan (*mangled)++; 1812169695Skan while (ISDIGIT ((unsigned char)**mangled)) 1813169695Skan { 1814169695Skan string_appendn (s, *mangled, 1); 1815169695Skan (*mangled)++; 1816169695Skan } 1817169695Skan } 1818169695Skan 1819169695Skan return 1; 1820169695Skan} 1821169695Skan 1822169695Skanstatic int 1823169695Skandemangle_template_value_parm (struct work_stuff *work, const char **mangled, 1824169695Skan string *s, type_kind_t tk) 1825169695Skan{ 1826169695Skan int success = 1; 1827169695Skan 1828169695Skan if (**mangled == 'Y') 1829169695Skan { 1830169695Skan /* The next argument is a template parameter. */ 1831169695Skan int idx; 1832169695Skan 1833169695Skan (*mangled)++; 1834169695Skan idx = consume_count_with_underscores (mangled); 1835169695Skan if (idx == -1 1836169695Skan || (work->tmpl_argvec && idx >= work->ntmpl_args) 1837169695Skan || consume_count_with_underscores (mangled) == -1) 1838169695Skan return -1; 1839169695Skan if (work->tmpl_argvec) 1840169695Skan string_append (s, work->tmpl_argvec[idx]); 1841169695Skan else 1842169695Skan string_append_template_idx (s, idx); 1843169695Skan } 1844169695Skan else if (tk == tk_integral) 1845169695Skan success = demangle_integral_value (work, mangled, s); 1846169695Skan else if (tk == tk_char) 1847169695Skan { 1848169695Skan char tmp[2]; 1849169695Skan int val; 1850169695Skan if (**mangled == 'm') 1851169695Skan { 1852169695Skan string_appendn (s, "-", 1); 1853169695Skan (*mangled)++; 1854169695Skan } 1855169695Skan string_appendn (s, "'", 1); 1856169695Skan val = consume_count(mangled); 1857169695Skan if (val <= 0) 1858169695Skan success = 0; 1859169695Skan else 1860169695Skan { 1861169695Skan tmp[0] = (char)val; 1862169695Skan tmp[1] = '\0'; 1863169695Skan string_appendn (s, &tmp[0], 1); 1864169695Skan string_appendn (s, "'", 1); 1865169695Skan } 1866169695Skan } 1867169695Skan else if (tk == tk_bool) 1868169695Skan { 1869169695Skan int val = consume_count (mangled); 1870169695Skan if (val == 0) 1871169695Skan string_appendn (s, "false", 5); 1872169695Skan else if (val == 1) 1873169695Skan string_appendn (s, "true", 4); 1874169695Skan else 1875169695Skan success = 0; 1876169695Skan } 1877169695Skan else if (tk == tk_real) 1878169695Skan success = demangle_real_value (work, mangled, s); 1879169695Skan else if (tk == tk_pointer || tk == tk_reference) 1880169695Skan { 1881169695Skan if (**mangled == 'Q') 1882169695Skan success = demangle_qualified (work, mangled, s, 1883169695Skan /*isfuncname=*/0, 1884169695Skan /*append=*/1); 1885169695Skan else 1886169695Skan { 1887169695Skan int symbol_len = consume_count (mangled); 1888169695Skan if (symbol_len == -1) 1889169695Skan return -1; 1890169695Skan if (symbol_len == 0) 1891169695Skan string_appendn (s, "0", 1); 1892169695Skan else 1893169695Skan { 1894169695Skan char *p = XNEWVEC (char, symbol_len + 1), *q; 1895169695Skan strncpy (p, *mangled, symbol_len); 1896169695Skan p [symbol_len] = '\0'; 1897169695Skan /* We use cplus_demangle here, rather than 1898169695Skan internal_cplus_demangle, because the name of the entity 1899169695Skan mangled here does not make use of any of the squangling 1900169695Skan or type-code information we have built up thus far; it is 1901169695Skan mangled independently. */ 1902169695Skan q = cplus_demangle (p, work->options); 1903169695Skan if (tk == tk_pointer) 1904169695Skan string_appendn (s, "&", 1); 1905169695Skan /* FIXME: Pointer-to-member constants should get a 1906169695Skan qualifying class name here. */ 1907169695Skan if (q) 1908169695Skan { 1909169695Skan string_append (s, q); 1910169695Skan free (q); 1911169695Skan } 1912169695Skan else 1913169695Skan string_append (s, p); 1914169695Skan free (p); 1915169695Skan } 1916169695Skan *mangled += symbol_len; 1917169695Skan } 1918169695Skan } 1919169695Skan 1920169695Skan return success; 1921169695Skan} 1922169695Skan 1923169695Skan/* Demangle the template name in MANGLED. The full name of the 1924169695Skan template (e.g., S<int>) is placed in TNAME. The name without the 1925169695Skan template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is 1926169695Skan non-NULL. If IS_TYPE is nonzero, this template is a type template, 1927169695Skan not a function template. If both IS_TYPE and REMEMBER are nonzero, 1928169695Skan the template is remembered in the list of back-referenceable 1929169695Skan types. */ 1930169695Skan 1931169695Skanstatic int 1932169695Skandemangle_template (struct work_stuff *work, const char **mangled, 1933169695Skan string *tname, string *trawname, 1934169695Skan int is_type, int remember) 1935169695Skan{ 1936169695Skan int i; 1937169695Skan int r; 1938169695Skan int need_comma = 0; 1939169695Skan int success = 0; 1940169695Skan int is_java_array = 0; 1941169695Skan string temp; 1942169695Skan 1943169695Skan (*mangled)++; 1944169695Skan if (is_type) 1945169695Skan { 1946169695Skan /* get template name */ 1947169695Skan if (**mangled == 'z') 1948169695Skan { 1949169695Skan int idx; 1950169695Skan (*mangled)++; 1951169695Skan (*mangled)++; 1952169695Skan 1953169695Skan idx = consume_count_with_underscores (mangled); 1954169695Skan if (idx == -1 1955169695Skan || (work->tmpl_argvec && idx >= work->ntmpl_args) 1956169695Skan || consume_count_with_underscores (mangled) == -1) 1957169695Skan return (0); 1958169695Skan 1959169695Skan if (work->tmpl_argvec) 1960169695Skan { 1961169695Skan string_append (tname, work->tmpl_argvec[idx]); 1962169695Skan if (trawname) 1963169695Skan string_append (trawname, work->tmpl_argvec[idx]); 1964169695Skan } 1965169695Skan else 1966169695Skan { 1967169695Skan string_append_template_idx (tname, idx); 1968169695Skan if (trawname) 1969169695Skan string_append_template_idx (trawname, idx); 1970169695Skan } 1971169695Skan } 1972169695Skan else 1973169695Skan { 1974169695Skan if ((r = consume_count (mangled)) <= 0 1975169695Skan || (int) strlen (*mangled) < r) 1976169695Skan { 1977169695Skan return (0); 1978169695Skan } 1979169695Skan is_java_array = (work -> options & DMGL_JAVA) 1980169695Skan && strncmp (*mangled, "JArray1Z", 8) == 0; 1981169695Skan if (! is_java_array) 1982169695Skan { 1983169695Skan string_appendn (tname, *mangled, r); 1984169695Skan } 1985169695Skan if (trawname) 1986169695Skan string_appendn (trawname, *mangled, r); 1987169695Skan *mangled += r; 1988169695Skan } 1989169695Skan } 1990169695Skan if (!is_java_array) 1991169695Skan string_append (tname, "<"); 1992169695Skan /* get size of template parameter list */ 1993169695Skan if (!get_count (mangled, &r)) 1994169695Skan { 1995169695Skan return (0); 1996169695Skan } 1997169695Skan if (!is_type) 1998169695Skan { 1999169695Skan /* Create an array for saving the template argument values. */ 2000169695Skan work->tmpl_argvec = XNEWVEC (char *, r); 2001169695Skan work->ntmpl_args = r; 2002169695Skan for (i = 0; i < r; i++) 2003169695Skan work->tmpl_argvec[i] = 0; 2004169695Skan } 2005169695Skan for (i = 0; i < r; i++) 2006169695Skan { 2007169695Skan if (need_comma) 2008169695Skan { 2009169695Skan string_append (tname, ", "); 2010169695Skan } 2011169695Skan /* Z for type parameters */ 2012169695Skan if (**mangled == 'Z') 2013169695Skan { 2014169695Skan (*mangled)++; 2015169695Skan /* temp is initialized in do_type */ 2016169695Skan success = do_type (work, mangled, &temp); 2017169695Skan if (success) 2018169695Skan { 2019169695Skan string_appends (tname, &temp); 2020169695Skan 2021169695Skan if (!is_type) 2022169695Skan { 2023169695Skan /* Save the template argument. */ 2024169695Skan int len = temp.p - temp.b; 2025169695Skan work->tmpl_argvec[i] = XNEWVEC (char, len + 1); 2026169695Skan memcpy (work->tmpl_argvec[i], temp.b, len); 2027169695Skan work->tmpl_argvec[i][len] = '\0'; 2028169695Skan } 2029169695Skan } 2030169695Skan string_delete(&temp); 2031169695Skan if (!success) 2032169695Skan { 2033169695Skan break; 2034169695Skan } 2035169695Skan } 2036169695Skan /* z for template parameters */ 2037169695Skan else if (**mangled == 'z') 2038169695Skan { 2039169695Skan int r2; 2040169695Skan (*mangled)++; 2041169695Skan success = demangle_template_template_parm (work, mangled, tname); 2042169695Skan 2043169695Skan if (success 2044169695Skan && (r2 = consume_count (mangled)) > 0 2045169695Skan && (int) strlen (*mangled) >= r2) 2046169695Skan { 2047169695Skan string_append (tname, " "); 2048169695Skan string_appendn (tname, *mangled, r2); 2049169695Skan if (!is_type) 2050169695Skan { 2051169695Skan /* Save the template argument. */ 2052169695Skan int len = r2; 2053169695Skan work->tmpl_argvec[i] = XNEWVEC (char, len + 1); 2054169695Skan memcpy (work->tmpl_argvec[i], *mangled, len); 2055169695Skan work->tmpl_argvec[i][len] = '\0'; 2056169695Skan } 2057169695Skan *mangled += r2; 2058169695Skan } 2059169695Skan if (!success) 2060169695Skan { 2061169695Skan break; 2062169695Skan } 2063169695Skan } 2064169695Skan else 2065169695Skan { 2066169695Skan string param; 2067169695Skan string* s; 2068169695Skan 2069169695Skan /* otherwise, value parameter */ 2070169695Skan 2071169695Skan /* temp is initialized in do_type */ 2072169695Skan success = do_type (work, mangled, &temp); 2073169695Skan string_delete(&temp); 2074169695Skan if (!success) 2075169695Skan break; 2076169695Skan 2077169695Skan if (!is_type) 2078169695Skan { 2079169695Skan s = ¶m; 2080169695Skan string_init (s); 2081169695Skan } 2082169695Skan else 2083169695Skan s = tname; 2084169695Skan 2085169695Skan success = demangle_template_value_parm (work, mangled, s, 2086169695Skan (type_kind_t) success); 2087169695Skan 2088169695Skan if (!success) 2089169695Skan { 2090169695Skan if (!is_type) 2091169695Skan string_delete (s); 2092169695Skan success = 0; 2093169695Skan break; 2094169695Skan } 2095169695Skan 2096169695Skan if (!is_type) 2097169695Skan { 2098169695Skan int len = s->p - s->b; 2099169695Skan work->tmpl_argvec[i] = XNEWVEC (char, len + 1); 2100169695Skan memcpy (work->tmpl_argvec[i], s->b, len); 2101169695Skan work->tmpl_argvec[i][len] = '\0'; 2102169695Skan 2103169695Skan string_appends (tname, s); 2104169695Skan string_delete (s); 2105169695Skan } 2106169695Skan } 2107169695Skan need_comma = 1; 2108169695Skan } 2109169695Skan if (is_java_array) 2110169695Skan { 2111169695Skan string_append (tname, "[]"); 2112169695Skan } 2113169695Skan else 2114169695Skan { 2115169695Skan if (tname->p[-1] == '>') 2116169695Skan string_append (tname, " "); 2117169695Skan string_append (tname, ">"); 2118169695Skan } 2119169695Skan 2120169695Skan if (is_type && remember) 2121169695Skan { 2122169695Skan const int bindex = register_Btype (work); 2123169695Skan remember_Btype (work, tname->b, LEN_STRING (tname), bindex); 2124169695Skan } 2125169695Skan 2126169695Skan /* 2127169695Skan if (work -> static_type) 2128169695Skan { 2129169695Skan string_append (declp, *mangled + 1); 2130169695Skan *mangled += strlen (*mangled); 2131169695Skan success = 1; 2132169695Skan } 2133169695Skan else 2134169695Skan { 2135169695Skan success = demangle_args (work, mangled, declp); 2136169695Skan } 2137169695Skan } 2138169695Skan */ 2139169695Skan return (success); 2140169695Skan} 2141169695Skan 2142169695Skanstatic int 2143169695Skanarm_pt (struct work_stuff *work, const char *mangled, 2144169695Skan int n, const char **anchor, const char **args) 2145169695Skan{ 2146169695Skan /* Check if ARM template with "__pt__" in it ("parameterized type") */ 2147169695Skan /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */ 2148169695Skan if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__"))) 2149169695Skan { 2150169695Skan int len; 2151169695Skan *args = *anchor + 6; 2152169695Skan len = consume_count (args); 2153169695Skan if (len == -1) 2154169695Skan return 0; 2155169695Skan if (*args + len == mangled + n && **args == '_') 2156169695Skan { 2157169695Skan ++*args; 2158169695Skan return 1; 2159169695Skan } 2160169695Skan } 2161169695Skan if (AUTO_DEMANGLING || EDG_DEMANGLING) 2162169695Skan { 2163169695Skan if ((*anchor = strstr (mangled, "__tm__")) 2164169695Skan || (*anchor = strstr (mangled, "__ps__")) 2165169695Skan || (*anchor = strstr (mangled, "__pt__"))) 2166169695Skan { 2167169695Skan int len; 2168169695Skan *args = *anchor + 6; 2169169695Skan len = consume_count (args); 2170169695Skan if (len == -1) 2171169695Skan return 0; 2172169695Skan if (*args + len == mangled + n && **args == '_') 2173169695Skan { 2174169695Skan ++*args; 2175169695Skan return 1; 2176169695Skan } 2177169695Skan } 2178169695Skan else if ((*anchor = strstr (mangled, "__S"))) 2179169695Skan { 2180169695Skan int len; 2181169695Skan *args = *anchor + 3; 2182169695Skan len = consume_count (args); 2183169695Skan if (len == -1) 2184169695Skan return 0; 2185169695Skan if (*args + len == mangled + n && **args == '_') 2186169695Skan { 2187169695Skan ++*args; 2188169695Skan return 1; 2189169695Skan } 2190169695Skan } 2191169695Skan } 2192169695Skan 2193169695Skan return 0; 2194169695Skan} 2195169695Skan 2196169695Skanstatic void 2197169695Skandemangle_arm_hp_template (struct work_stuff *work, const char **mangled, 2198169695Skan int n, string *declp) 2199169695Skan{ 2200169695Skan const char *p; 2201169695Skan const char *args; 2202169695Skan const char *e = *mangled + n; 2203169695Skan string arg; 2204169695Skan 2205169695Skan /* Check for HP aCC template spec: classXt1t2 where t1, t2 are 2206169695Skan template args */ 2207169695Skan if (HP_DEMANGLING && ((*mangled)[n] == 'X')) 2208169695Skan { 2209169695Skan char *start_spec_args = NULL; 2210169695Skan int hold_options; 2211169695Skan 2212169695Skan /* First check for and omit template specialization pseudo-arguments, 2213169695Skan such as in "Spec<#1,#1.*>" */ 2214169695Skan start_spec_args = strchr (*mangled, '<'); 2215169695Skan if (start_spec_args && (start_spec_args - *mangled < n)) 2216169695Skan string_appendn (declp, *mangled, start_spec_args - *mangled); 2217169695Skan else 2218169695Skan string_appendn (declp, *mangled, n); 2219169695Skan (*mangled) += n + 1; 2220169695Skan string_init (&arg); 2221169695Skan if (work->temp_start == -1) /* non-recursive call */ 2222169695Skan work->temp_start = declp->p - declp->b; 2223169695Skan 2224169695Skan /* We want to unconditionally demangle parameter types in 2225169695Skan template parameters. */ 2226169695Skan hold_options = work->options; 2227169695Skan work->options |= DMGL_PARAMS; 2228169695Skan 2229169695Skan string_append (declp, "<"); 2230169695Skan while (1) 2231169695Skan { 2232169695Skan string_delete (&arg); 2233169695Skan switch (**mangled) 2234169695Skan { 2235169695Skan case 'T': 2236169695Skan /* 'T' signals a type parameter */ 2237169695Skan (*mangled)++; 2238169695Skan if (!do_type (work, mangled, &arg)) 2239169695Skan goto hpacc_template_args_done; 2240169695Skan break; 2241169695Skan 2242169695Skan case 'U': 2243169695Skan case 'S': 2244169695Skan /* 'U' or 'S' signals an integral value */ 2245169695Skan if (!do_hpacc_template_const_value (work, mangled, &arg)) 2246169695Skan goto hpacc_template_args_done; 2247169695Skan break; 2248169695Skan 2249169695Skan case 'A': 2250169695Skan /* 'A' signals a named constant expression (literal) */ 2251169695Skan if (!do_hpacc_template_literal (work, mangled, &arg)) 2252169695Skan goto hpacc_template_args_done; 2253169695Skan break; 2254169695Skan 2255169695Skan default: 2256169695Skan /* Today, 1997-09-03, we have only the above types 2257169695Skan of template parameters */ 2258169695Skan /* FIXME: maybe this should fail and return null */ 2259169695Skan goto hpacc_template_args_done; 2260169695Skan } 2261169695Skan string_appends (declp, &arg); 2262169695Skan /* Check if we're at the end of template args. 2263169695Skan 0 if at end of static member of template class, 2264169695Skan _ if done with template args for a function */ 2265169695Skan if ((**mangled == '\000') || (**mangled == '_')) 2266169695Skan break; 2267169695Skan else 2268169695Skan string_append (declp, ","); 2269169695Skan } 2270169695Skan hpacc_template_args_done: 2271169695Skan string_append (declp, ">"); 2272169695Skan string_delete (&arg); 2273169695Skan if (**mangled == '_') 2274169695Skan (*mangled)++; 2275169695Skan work->options = hold_options; 2276169695Skan return; 2277169695Skan } 2278169695Skan /* ARM template? (Also handles HP cfront extensions) */ 2279169695Skan else if (arm_pt (work, *mangled, n, &p, &args)) 2280169695Skan { 2281169695Skan int hold_options; 2282169695Skan string type_str; 2283169695Skan 2284169695Skan string_init (&arg); 2285169695Skan string_appendn (declp, *mangled, p - *mangled); 2286169695Skan if (work->temp_start == -1) /* non-recursive call */ 2287169695Skan work->temp_start = declp->p - declp->b; 2288169695Skan 2289169695Skan /* We want to unconditionally demangle parameter types in 2290169695Skan template parameters. */ 2291169695Skan hold_options = work->options; 2292169695Skan work->options |= DMGL_PARAMS; 2293169695Skan 2294169695Skan string_append (declp, "<"); 2295169695Skan /* should do error checking here */ 2296169695Skan while (args < e) { 2297169695Skan string_delete (&arg); 2298169695Skan 2299169695Skan /* Check for type or literal here */ 2300169695Skan switch (*args) 2301169695Skan { 2302169695Skan /* HP cfront extensions to ARM for template args */ 2303169695Skan /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */ 2304169695Skan /* FIXME: We handle only numeric literals for HP cfront */ 2305169695Skan case 'X': 2306169695Skan /* A typed constant value follows */ 2307169695Skan args++; 2308169695Skan if (!do_type (work, &args, &type_str)) 2309169695Skan goto cfront_template_args_done; 2310169695Skan string_append (&arg, "("); 2311169695Skan string_appends (&arg, &type_str); 2312169695Skan string_delete (&type_str); 2313169695Skan string_append (&arg, ")"); 2314169695Skan if (*args != 'L') 2315169695Skan goto cfront_template_args_done; 2316169695Skan args++; 2317169695Skan /* Now snarf a literal value following 'L' */ 2318169695Skan if (!snarf_numeric_literal (&args, &arg)) 2319169695Skan goto cfront_template_args_done; 2320169695Skan break; 2321169695Skan 2322169695Skan case 'L': 2323169695Skan /* Snarf a literal following 'L' */ 2324169695Skan args++; 2325169695Skan if (!snarf_numeric_literal (&args, &arg)) 2326169695Skan goto cfront_template_args_done; 2327169695Skan break; 2328169695Skan default: 2329169695Skan /* Not handling other HP cfront stuff */ 2330169695Skan { 2331169695Skan const char* old_args = args; 2332169695Skan if (!do_type (work, &args, &arg)) 2333169695Skan goto cfront_template_args_done; 2334169695Skan 2335169695Skan /* Fail if we didn't make any progress: prevent infinite loop. */ 2336169695Skan if (args == old_args) 2337169695Skan { 2338169695Skan work->options = hold_options; 2339169695Skan return; 2340169695Skan } 2341169695Skan } 2342169695Skan } 2343169695Skan string_appends (declp, &arg); 2344169695Skan string_append (declp, ","); 2345169695Skan } 2346169695Skan cfront_template_args_done: 2347169695Skan string_delete (&arg); 2348169695Skan if (args >= e) 2349169695Skan --declp->p; /* remove extra comma */ 2350169695Skan string_append (declp, ">"); 2351169695Skan work->options = hold_options; 2352169695Skan } 2353169695Skan else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0 2354169695Skan && (*mangled)[9] == 'N' 2355169695Skan && (*mangled)[8] == (*mangled)[10] 2356169695Skan && strchr (cplus_markers, (*mangled)[8])) 2357169695Skan { 2358169695Skan /* A member of the anonymous namespace. */ 2359169695Skan string_append (declp, "{anonymous}"); 2360169695Skan } 2361169695Skan else 2362169695Skan { 2363169695Skan if (work->temp_start == -1) /* non-recursive call only */ 2364169695Skan work->temp_start = 0; /* disable in recursive calls */ 2365169695Skan string_appendn (declp, *mangled, n); 2366169695Skan } 2367169695Skan *mangled += n; 2368169695Skan} 2369169695Skan 2370169695Skan/* Extract a class name, possibly a template with arguments, from the 2371169695Skan mangled string; qualifiers, local class indicators, etc. have 2372169695Skan already been dealt with */ 2373169695Skan 2374169695Skanstatic int 2375169695Skandemangle_class_name (struct work_stuff *work, const char **mangled, 2376169695Skan string *declp) 2377169695Skan{ 2378169695Skan int n; 2379169695Skan int success = 0; 2380169695Skan 2381169695Skan n = consume_count (mangled); 2382169695Skan if (n == -1) 2383169695Skan return 0; 2384169695Skan if ((int) strlen (*mangled) >= n) 2385169695Skan { 2386169695Skan demangle_arm_hp_template (work, mangled, n, declp); 2387169695Skan success = 1; 2388169695Skan } 2389169695Skan 2390169695Skan return (success); 2391169695Skan} 2392169695Skan 2393169695Skan/* 2394169695Skan 2395169695SkanLOCAL FUNCTION 2396169695Skan 2397169695Skan demangle_class -- demangle a mangled class sequence 2398169695Skan 2399169695SkanSYNOPSIS 2400169695Skan 2401169695Skan static int 2402169695Skan demangle_class (struct work_stuff *work, const char **mangled, 2403169695Skan strint *declp) 2404169695Skan 2405169695SkanDESCRIPTION 2406169695Skan 2407169695Skan DECLP points to the buffer into which demangling is being done. 2408169695Skan 2409169695Skan *MANGLED points to the current token to be demangled. On input, 2410169695Skan it points to a mangled class (I.E. "3foo", "13verylongclass", etc.) 2411169695Skan On exit, it points to the next token after the mangled class on 2412169695Skan success, or the first unconsumed token on failure. 2413169695Skan 2414169695Skan If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then 2415169695Skan we are demangling a constructor or destructor. In this case 2416169695Skan we prepend "class::class" or "class::~class" to DECLP. 2417169695Skan 2418169695Skan Otherwise, we prepend "class::" to the current DECLP. 2419169695Skan 2420169695Skan Reset the constructor/destructor flags once they have been 2421169695Skan "consumed". This allows demangle_class to be called later during 2422169695Skan the same demangling, to do normal class demangling. 2423169695Skan 2424169695Skan Returns 1 if demangling is successful, 0 otherwise. 2425169695Skan 2426169695Skan*/ 2427169695Skan 2428169695Skanstatic int 2429169695Skandemangle_class (struct work_stuff *work, const char **mangled, string *declp) 2430169695Skan{ 2431169695Skan int success = 0; 2432169695Skan int btype; 2433169695Skan string class_name; 2434169695Skan char *save_class_name_end = 0; 2435169695Skan 2436169695Skan string_init (&class_name); 2437169695Skan btype = register_Btype (work); 2438169695Skan if (demangle_class_name (work, mangled, &class_name)) 2439169695Skan { 2440169695Skan save_class_name_end = class_name.p; 2441169695Skan if ((work->constructor & 1) || (work->destructor & 1)) 2442169695Skan { 2443169695Skan /* adjust so we don't include template args */ 2444169695Skan if (work->temp_start && (work->temp_start != -1)) 2445169695Skan { 2446169695Skan class_name.p = class_name.b + work->temp_start; 2447169695Skan } 2448169695Skan string_prepends (declp, &class_name); 2449169695Skan if (work -> destructor & 1) 2450169695Skan { 2451169695Skan string_prepend (declp, "~"); 2452169695Skan work -> destructor -= 1; 2453169695Skan } 2454169695Skan else 2455169695Skan { 2456169695Skan work -> constructor -= 1; 2457169695Skan } 2458169695Skan } 2459169695Skan class_name.p = save_class_name_end; 2460169695Skan remember_Ktype (work, class_name.b, LEN_STRING(&class_name)); 2461169695Skan remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype); 2462169695Skan string_prepend (declp, SCOPE_STRING (work)); 2463169695Skan string_prepends (declp, &class_name); 2464169695Skan success = 1; 2465169695Skan } 2466169695Skan string_delete (&class_name); 2467169695Skan return (success); 2468169695Skan} 2469169695Skan 2470169695Skan 2471169695Skan/* Called when there's a "__" in the mangled name, with `scan' pointing to 2472169695Skan the rightmost guess. 2473169695Skan 2474169695Skan Find the correct "__"-sequence where the function name ends and the 2475169695Skan signature starts, which is ambiguous with GNU mangling. 2476169695Skan Call demangle_signature here, so we can make sure we found the right 2477169695Skan one; *mangled will be consumed so caller will not make further calls to 2478169695Skan demangle_signature. */ 2479169695Skan 2480169695Skanstatic int 2481169695Skaniterate_demangle_function (struct work_stuff *work, const char **mangled, 2482169695Skan string *declp, const char *scan) 2483169695Skan{ 2484169695Skan const char *mangle_init = *mangled; 2485169695Skan int success = 0; 2486169695Skan string decl_init; 2487169695Skan struct work_stuff work_init; 2488169695Skan 2489169695Skan if (*(scan + 2) == '\0') 2490169695Skan return 0; 2491169695Skan 2492169695Skan /* Do not iterate for some demangling modes, or if there's only one 2493169695Skan "__"-sequence. This is the normal case. */ 2494169695Skan if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING 2495169695Skan || strstr (scan + 2, "__") == NULL) 2496169695Skan { 2497169695Skan demangle_function_name (work, mangled, declp, scan); 2498169695Skan return 1; 2499169695Skan } 2500169695Skan 2501169695Skan /* Save state so we can restart if the guess at the correct "__" was 2502169695Skan wrong. */ 2503169695Skan string_init (&decl_init); 2504169695Skan string_appends (&decl_init, declp); 2505169695Skan memset (&work_init, 0, sizeof work_init); 2506169695Skan work_stuff_copy_to_from (&work_init, work); 2507169695Skan 2508169695Skan /* Iterate over occurrences of __, allowing names and types to have a 2509169695Skan "__" sequence in them. We must start with the first (not the last) 2510169695Skan occurrence, since "__" most often occur between independent mangled 2511169695Skan parts, hence starting at the last occurence inside a signature 2512169695Skan might get us a "successful" demangling of the signature. */ 2513169695Skan 2514169695Skan while (scan[2]) 2515169695Skan { 2516169695Skan demangle_function_name (work, mangled, declp, scan); 2517169695Skan success = demangle_signature (work, mangled, declp); 2518169695Skan if (success) 2519169695Skan break; 2520169695Skan 2521169695Skan /* Reset demangle state for the next round. */ 2522169695Skan *mangled = mangle_init; 2523169695Skan string_clear (declp); 2524169695Skan string_appends (declp, &decl_init); 2525169695Skan work_stuff_copy_to_from (work, &work_init); 2526169695Skan 2527169695Skan /* Leave this underscore-sequence. */ 2528169695Skan scan += 2; 2529169695Skan 2530169695Skan /* Scan for the next "__" sequence. */ 2531169695Skan while (*scan && (scan[0] != '_' || scan[1] != '_')) 2532169695Skan scan++; 2533169695Skan 2534169695Skan /* Move to last "__" in this sequence. */ 2535169695Skan while (*scan && *scan == '_') 2536169695Skan scan++; 2537169695Skan scan -= 2; 2538169695Skan } 2539169695Skan 2540169695Skan /* Delete saved state. */ 2541169695Skan delete_work_stuff (&work_init); 2542169695Skan string_delete (&decl_init); 2543169695Skan 2544169695Skan return success; 2545169695Skan} 2546169695Skan 2547169695Skan/* 2548169695Skan 2549169695SkanLOCAL FUNCTION 2550169695Skan 2551169695Skan demangle_prefix -- consume the mangled name prefix and find signature 2552169695Skan 2553169695SkanSYNOPSIS 2554169695Skan 2555169695Skan static int 2556169695Skan demangle_prefix (struct work_stuff *work, const char **mangled, 2557169695Skan string *declp); 2558169695Skan 2559169695SkanDESCRIPTION 2560169695Skan 2561169695Skan Consume and demangle the prefix of the mangled name. 2562169695Skan While processing the function name root, arrange to call 2563169695Skan demangle_signature if the root is ambiguous. 2564169695Skan 2565169695Skan DECLP points to the string buffer into which demangled output is 2566169695Skan placed. On entry, the buffer is empty. On exit it contains 2567169695Skan the root function name, the demangled operator name, or in some 2568169695Skan special cases either nothing or the completely demangled result. 2569169695Skan 2570169695Skan MANGLED points to the current pointer into the mangled name. As each 2571169695Skan token of the mangled name is consumed, it is updated. Upon entry 2572169695Skan the current mangled name pointer points to the first character of 2573169695Skan the mangled name. Upon exit, it should point to the first character 2574169695Skan of the signature if demangling was successful, or to the first 2575169695Skan unconsumed character if demangling of the prefix was unsuccessful. 2576169695Skan 2577169695Skan Returns 1 on success, 0 otherwise. 2578169695Skan */ 2579169695Skan 2580169695Skanstatic int 2581169695Skandemangle_prefix (struct work_stuff *work, const char **mangled, 2582169695Skan string *declp) 2583169695Skan{ 2584169695Skan int success = 1; 2585169695Skan const char *scan; 2586169695Skan int i; 2587169695Skan 2588169695Skan if (strlen(*mangled) > 6 2589169695Skan && (strncmp(*mangled, "_imp__", 6) == 0 2590169695Skan || strncmp(*mangled, "__imp_", 6) == 0)) 2591169695Skan { 2592169695Skan /* it's a symbol imported from a PE dynamic library. Check for both 2593169695Skan new style prefix _imp__ and legacy __imp_ used by older versions 2594169695Skan of dlltool. */ 2595169695Skan (*mangled) += 6; 2596169695Skan work->dllimported = 1; 2597169695Skan } 2598169695Skan else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0) 2599169695Skan { 2600169695Skan char *marker = strchr (cplus_markers, (*mangled)[8]); 2601169695Skan if (marker != NULL && *marker == (*mangled)[10]) 2602169695Skan { 2603169695Skan if ((*mangled)[9] == 'D') 2604169695Skan { 2605169695Skan /* it's a GNU global destructor to be executed at program exit */ 2606169695Skan (*mangled) += 11; 2607169695Skan work->destructor = 2; 2608169695Skan if (gnu_special (work, mangled, declp)) 2609169695Skan return success; 2610169695Skan } 2611169695Skan else if ((*mangled)[9] == 'I') 2612169695Skan { 2613169695Skan /* it's a GNU global constructor to be executed at program init */ 2614169695Skan (*mangled) += 11; 2615169695Skan work->constructor = 2; 2616169695Skan if (gnu_special (work, mangled, declp)) 2617169695Skan return success; 2618169695Skan } 2619169695Skan } 2620169695Skan } 2621169695Skan else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0) 2622169695Skan { 2623169695Skan /* it's a ARM global destructor to be executed at program exit */ 2624169695Skan (*mangled) += 7; 2625169695Skan work->destructor = 2; 2626169695Skan } 2627169695Skan else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0) 2628169695Skan { 2629169695Skan /* it's a ARM global constructor to be executed at program initial */ 2630169695Skan (*mangled) += 7; 2631169695Skan work->constructor = 2; 2632169695Skan } 2633169695Skan 2634169695Skan /* This block of code is a reduction in strength time optimization 2635169695Skan of: 2636169695Skan scan = strstr (*mangled, "__"); */ 2637169695Skan 2638169695Skan { 2639169695Skan scan = *mangled; 2640169695Skan 2641169695Skan do { 2642169695Skan scan = strchr (scan, '_'); 2643169695Skan } while (scan != NULL && *++scan != '_'); 2644169695Skan 2645169695Skan if (scan != NULL) --scan; 2646169695Skan } 2647169695Skan 2648169695Skan if (scan != NULL) 2649169695Skan { 2650169695Skan /* We found a sequence of two or more '_', ensure that we start at 2651169695Skan the last pair in the sequence. */ 2652169695Skan i = strspn (scan, "_"); 2653169695Skan if (i > 2) 2654169695Skan { 2655169695Skan scan += (i - 2); 2656169695Skan } 2657169695Skan } 2658169695Skan 2659169695Skan if (scan == NULL) 2660169695Skan { 2661169695Skan success = 0; 2662169695Skan } 2663169695Skan else if (work -> static_type) 2664169695Skan { 2665169695Skan if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't')) 2666169695Skan { 2667169695Skan success = 0; 2668169695Skan } 2669169695Skan } 2670169695Skan else if ((scan == *mangled) 2671169695Skan && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q') 2672169695Skan || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H'))) 2673169695Skan { 2674169695Skan /* The ARM says nothing about the mangling of local variables. 2675169695Skan But cfront mangles local variables by prepending __<nesting_level> 2676169695Skan to them. As an extension to ARM demangling we handle this case. */ 2677169695Skan if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING) 2678169695Skan && ISDIGIT ((unsigned char)scan[2])) 2679169695Skan { 2680169695Skan *mangled = scan + 2; 2681169695Skan consume_count (mangled); 2682169695Skan string_append (declp, *mangled); 2683169695Skan *mangled += strlen (*mangled); 2684169695Skan success = 1; 2685169695Skan } 2686169695Skan else 2687169695Skan { 2688169695Skan /* A GNU style constructor starts with __[0-9Qt]. But cfront uses 2689169695Skan names like __Q2_3foo3bar for nested type names. So don't accept 2690169695Skan this style of constructor for cfront demangling. A GNU 2691169695Skan style member-template constructor starts with 'H'. */ 2692169695Skan if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)) 2693169695Skan work -> constructor += 1; 2694169695Skan *mangled = scan + 2; 2695169695Skan } 2696169695Skan } 2697169695Skan else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't') 2698169695Skan { 2699169695Skan /* Cfront-style parameterized type. Handled later as a signature. */ 2700169695Skan success = 1; 2701169695Skan 2702169695Skan /* ARM template? */ 2703169695Skan demangle_arm_hp_template (work, mangled, strlen (*mangled), declp); 2704169695Skan } 2705169695Skan else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm') 2706169695Skan || (scan[2] == 'p' && scan[3] == 's') 2707169695Skan || (scan[2] == 'p' && scan[3] == 't'))) 2708169695Skan { 2709169695Skan /* EDG-style parameterized type. Handled later as a signature. */ 2710169695Skan success = 1; 2711169695Skan 2712169695Skan /* EDG template? */ 2713169695Skan demangle_arm_hp_template (work, mangled, strlen (*mangled), declp); 2714169695Skan } 2715169695Skan else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2]) 2716169695Skan && (scan[2] != 't')) 2717169695Skan { 2718169695Skan /* Mangled name starts with "__". Skip over any leading '_' characters, 2719169695Skan then find the next "__" that separates the prefix from the signature. 2720169695Skan */ 2721169695Skan if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) 2722169695Skan || (arm_special (mangled, declp) == 0)) 2723169695Skan { 2724169695Skan while (*scan == '_') 2725169695Skan { 2726169695Skan scan++; 2727169695Skan } 2728169695Skan if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0')) 2729169695Skan { 2730169695Skan /* No separator (I.E. "__not_mangled"), or empty signature 2731169695Skan (I.E. "__not_mangled_either__") */ 2732169695Skan success = 0; 2733169695Skan } 2734169695Skan else 2735169695Skan return iterate_demangle_function (work, mangled, declp, scan); 2736169695Skan } 2737169695Skan } 2738169695Skan else if (*(scan + 2) != '\0') 2739169695Skan { 2740169695Skan /* Mangled name does not start with "__" but does have one somewhere 2741169695Skan in there with non empty stuff after it. Looks like a global 2742169695Skan function name. Iterate over all "__":s until the right 2743169695Skan one is found. */ 2744169695Skan return iterate_demangle_function (work, mangled, declp, scan); 2745169695Skan } 2746169695Skan else 2747169695Skan { 2748169695Skan /* Doesn't look like a mangled name */ 2749169695Skan success = 0; 2750169695Skan } 2751169695Skan 2752169695Skan if (!success && (work->constructor == 2 || work->destructor == 2)) 2753169695Skan { 2754169695Skan string_append (declp, *mangled); 2755169695Skan *mangled += strlen (*mangled); 2756169695Skan success = 1; 2757169695Skan } 2758169695Skan return (success); 2759169695Skan} 2760169695Skan 2761169695Skan/* 2762169695Skan 2763169695SkanLOCAL FUNCTION 2764169695Skan 2765169695Skan gnu_special -- special handling of gnu mangled strings 2766169695Skan 2767169695SkanSYNOPSIS 2768169695Skan 2769169695Skan static int 2770169695Skan gnu_special (struct work_stuff *work, const char **mangled, 2771169695Skan string *declp); 2772169695Skan 2773169695Skan 2774169695SkanDESCRIPTION 2775169695Skan 2776169695Skan Process some special GNU style mangling forms that don't fit 2777169695Skan the normal pattern. For example: 2778169695Skan 2779169695Skan _$_3foo (destructor for class foo) 2780169695Skan _vt$foo (foo virtual table) 2781169695Skan _vt$foo$bar (foo::bar virtual table) 2782169695Skan __vt_foo (foo virtual table, new style with thunks) 2783169695Skan _3foo$varname (static data member) 2784169695Skan _Q22rs2tu$vw (static data member) 2785169695Skan __t6vector1Zii (constructor with template) 2786169695Skan __thunk_4__$_7ostream (virtual function thunk) 2787169695Skan */ 2788169695Skan 2789169695Skanstatic int 2790169695Skangnu_special (struct work_stuff *work, const char **mangled, string *declp) 2791169695Skan{ 2792169695Skan int n; 2793169695Skan int success = 1; 2794169695Skan const char *p; 2795169695Skan 2796169695Skan if ((*mangled)[0] == '_' 2797169695Skan && strchr (cplus_markers, (*mangled)[1]) != NULL 2798169695Skan && (*mangled)[2] == '_') 2799169695Skan { 2800169695Skan /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */ 2801169695Skan (*mangled) += 3; 2802169695Skan work -> destructor += 1; 2803169695Skan } 2804169695Skan else if ((*mangled)[0] == '_' 2805169695Skan && (((*mangled)[1] == '_' 2806169695Skan && (*mangled)[2] == 'v' 2807169695Skan && (*mangled)[3] == 't' 2808169695Skan && (*mangled)[4] == '_') 2809169695Skan || ((*mangled)[1] == 'v' 2810169695Skan && (*mangled)[2] == 't' 2811169695Skan && strchr (cplus_markers, (*mangled)[3]) != NULL))) 2812169695Skan { 2813169695Skan /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>" 2814169695Skan and create the decl. Note that we consume the entire mangled 2815169695Skan input string, which means that demangle_signature has no work 2816169695Skan to do. */ 2817169695Skan if ((*mangled)[2] == 'v') 2818169695Skan (*mangled) += 5; /* New style, with thunks: "__vt_" */ 2819169695Skan else 2820169695Skan (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */ 2821169695Skan while (**mangled != '\0') 2822169695Skan { 2823169695Skan switch (**mangled) 2824169695Skan { 2825169695Skan case 'Q': 2826169695Skan case 'K': 2827169695Skan success = demangle_qualified (work, mangled, declp, 0, 1); 2828169695Skan break; 2829169695Skan case 't': 2830169695Skan success = demangle_template (work, mangled, declp, 0, 1, 2831169695Skan 1); 2832169695Skan break; 2833169695Skan default: 2834169695Skan if (ISDIGIT((unsigned char)*mangled[0])) 2835169695Skan { 2836169695Skan n = consume_count(mangled); 2837169695Skan /* We may be seeing a too-large size, or else a 2838169695Skan ".<digits>" indicating a static local symbol. In 2839169695Skan any case, declare victory and move on; *don't* try 2840169695Skan to use n to allocate. */ 2841169695Skan if (n > (int) strlen (*mangled)) 2842169695Skan { 2843169695Skan success = 1; 2844169695Skan break; 2845169695Skan } 2846169695Skan } 2847169695Skan else 2848169695Skan { 2849169695Skan n = strcspn (*mangled, cplus_markers); 2850169695Skan } 2851169695Skan string_appendn (declp, *mangled, n); 2852169695Skan (*mangled) += n; 2853169695Skan } 2854169695Skan 2855169695Skan p = strpbrk (*mangled, cplus_markers); 2856169695Skan if (success && ((p == NULL) || (p == *mangled))) 2857169695Skan { 2858169695Skan if (p != NULL) 2859169695Skan { 2860169695Skan string_append (declp, SCOPE_STRING (work)); 2861169695Skan (*mangled)++; 2862169695Skan } 2863169695Skan } 2864169695Skan else 2865169695Skan { 2866169695Skan success = 0; 2867169695Skan break; 2868169695Skan } 2869169695Skan } 2870169695Skan if (success) 2871169695Skan string_append (declp, " virtual table"); 2872169695Skan } 2873169695Skan else if ((*mangled)[0] == '_' 2874169695Skan && (strchr("0123456789Qt", (*mangled)[1]) != NULL) 2875169695Skan && (p = strpbrk (*mangled, cplus_markers)) != NULL) 2876169695Skan { 2877169695Skan /* static data member, "_3foo$varname" for example */ 2878169695Skan (*mangled)++; 2879169695Skan switch (**mangled) 2880169695Skan { 2881169695Skan case 'Q': 2882169695Skan case 'K': 2883169695Skan success = demangle_qualified (work, mangled, declp, 0, 1); 2884169695Skan break; 2885169695Skan case 't': 2886169695Skan success = demangle_template (work, mangled, declp, 0, 1, 1); 2887169695Skan break; 2888169695Skan default: 2889169695Skan n = consume_count (mangled); 2890169695Skan if (n < 0 || n > (long) strlen (*mangled)) 2891169695Skan { 2892169695Skan success = 0; 2893169695Skan break; 2894169695Skan } 2895169695Skan 2896169695Skan if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0 2897169695Skan && (*mangled)[9] == 'N' 2898169695Skan && (*mangled)[8] == (*mangled)[10] 2899169695Skan && strchr (cplus_markers, (*mangled)[8])) 2900169695Skan { 2901169695Skan /* A member of the anonymous namespace. There's information 2902169695Skan about what identifier or filename it was keyed to, but 2903169695Skan it's just there to make the mangled name unique; we just 2904169695Skan step over it. */ 2905169695Skan string_append (declp, "{anonymous}"); 2906169695Skan (*mangled) += n; 2907169695Skan 2908169695Skan /* Now p points to the marker before the N, so we need to 2909169695Skan update it to the first marker after what we consumed. */ 2910169695Skan p = strpbrk (*mangled, cplus_markers); 2911169695Skan break; 2912169695Skan } 2913169695Skan 2914169695Skan string_appendn (declp, *mangled, n); 2915169695Skan (*mangled) += n; 2916169695Skan } 2917169695Skan if (success && (p == *mangled)) 2918169695Skan { 2919169695Skan /* Consumed everything up to the cplus_marker, append the 2920169695Skan variable name. */ 2921169695Skan (*mangled)++; 2922169695Skan string_append (declp, SCOPE_STRING (work)); 2923169695Skan n = strlen (*mangled); 2924169695Skan string_appendn (declp, *mangled, n); 2925169695Skan (*mangled) += n; 2926169695Skan } 2927169695Skan else 2928169695Skan { 2929169695Skan success = 0; 2930169695Skan } 2931169695Skan } 2932169695Skan else if (strncmp (*mangled, "__thunk_", 8) == 0) 2933169695Skan { 2934169695Skan int delta; 2935169695Skan 2936169695Skan (*mangled) += 8; 2937169695Skan delta = consume_count (mangled); 2938169695Skan if (delta == -1) 2939169695Skan success = 0; 2940169695Skan else 2941169695Skan { 2942169695Skan char *method = internal_cplus_demangle (work, ++*mangled); 2943169695Skan 2944169695Skan if (method) 2945169695Skan { 2946169695Skan char buf[50]; 2947169695Skan sprintf (buf, "virtual function thunk (delta:%d) for ", -delta); 2948169695Skan string_append (declp, buf); 2949169695Skan string_append (declp, method); 2950169695Skan free (method); 2951169695Skan n = strlen (*mangled); 2952169695Skan (*mangled) += n; 2953169695Skan } 2954169695Skan else 2955169695Skan { 2956169695Skan success = 0; 2957169695Skan } 2958169695Skan } 2959169695Skan } 2960169695Skan else if (strncmp (*mangled, "__t", 3) == 0 2961169695Skan && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f')) 2962169695Skan { 2963169695Skan p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function"; 2964169695Skan (*mangled) += 4; 2965169695Skan switch (**mangled) 2966169695Skan { 2967169695Skan case 'Q': 2968169695Skan case 'K': 2969169695Skan success = demangle_qualified (work, mangled, declp, 0, 1); 2970169695Skan break; 2971169695Skan case 't': 2972169695Skan success = demangle_template (work, mangled, declp, 0, 1, 1); 2973169695Skan break; 2974169695Skan default: 2975169695Skan success = do_type (work, mangled, declp); 2976169695Skan break; 2977169695Skan } 2978169695Skan if (success && **mangled != '\0') 2979169695Skan success = 0; 2980169695Skan if (success) 2981169695Skan string_append (declp, p); 2982169695Skan } 2983169695Skan else 2984169695Skan { 2985169695Skan success = 0; 2986169695Skan } 2987169695Skan return (success); 2988169695Skan} 2989169695Skan 2990169695Skanstatic void 2991169695Skanrecursively_demangle(struct work_stuff *work, const char **mangled, 2992169695Skan string *result, int namelength) 2993169695Skan{ 2994169695Skan char * recurse = (char *)NULL; 2995169695Skan char * recurse_dem = (char *)NULL; 2996169695Skan 2997169695Skan recurse = XNEWVEC (char, namelength + 1); 2998169695Skan memcpy (recurse, *mangled, namelength); 2999169695Skan recurse[namelength] = '\000'; 3000169695Skan 3001169695Skan recurse_dem = cplus_demangle (recurse, work->options); 3002169695Skan 3003169695Skan if (recurse_dem) 3004169695Skan { 3005169695Skan string_append (result, recurse_dem); 3006169695Skan free (recurse_dem); 3007169695Skan } 3008169695Skan else 3009169695Skan { 3010169695Skan string_appendn (result, *mangled, namelength); 3011169695Skan } 3012169695Skan free (recurse); 3013169695Skan *mangled += namelength; 3014169695Skan} 3015169695Skan 3016169695Skan/* 3017169695Skan 3018169695SkanLOCAL FUNCTION 3019169695Skan 3020169695Skan arm_special -- special handling of ARM/lucid mangled strings 3021169695Skan 3022169695SkanSYNOPSIS 3023169695Skan 3024169695Skan static int 3025169695Skan arm_special (const char **mangled, 3026169695Skan string *declp); 3027169695Skan 3028169695Skan 3029169695SkanDESCRIPTION 3030169695Skan 3031169695Skan Process some special ARM style mangling forms that don't fit 3032169695Skan the normal pattern. For example: 3033169695Skan 3034169695Skan __vtbl__3foo (foo virtual table) 3035169695Skan __vtbl__3foo__3bar (bar::foo virtual table) 3036169695Skan 3037169695Skan */ 3038169695Skan 3039169695Skanstatic int 3040169695Skanarm_special (const char **mangled, string *declp) 3041169695Skan{ 3042169695Skan int n; 3043169695Skan int success = 1; 3044169695Skan const char *scan; 3045169695Skan 3046169695Skan if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0) 3047169695Skan { 3048169695Skan /* Found a ARM style virtual table, get past ARM_VTABLE_STRING 3049169695Skan and create the decl. Note that we consume the entire mangled 3050169695Skan input string, which means that demangle_signature has no work 3051169695Skan to do. */ 3052169695Skan scan = *mangled + ARM_VTABLE_STRLEN; 3053169695Skan while (*scan != '\0') /* first check it can be demangled */ 3054169695Skan { 3055169695Skan n = consume_count (&scan); 3056169695Skan if (n == -1) 3057169695Skan { 3058169695Skan return (0); /* no good */ 3059169695Skan } 3060169695Skan scan += n; 3061169695Skan if (scan[0] == '_' && scan[1] == '_') 3062169695Skan { 3063169695Skan scan += 2; 3064169695Skan } 3065169695Skan } 3066169695Skan (*mangled) += ARM_VTABLE_STRLEN; 3067169695Skan while (**mangled != '\0') 3068169695Skan { 3069169695Skan n = consume_count (mangled); 3070169695Skan if (n == -1 3071169695Skan || n > (long) strlen (*mangled)) 3072169695Skan return 0; 3073169695Skan string_prependn (declp, *mangled, n); 3074169695Skan (*mangled) += n; 3075169695Skan if ((*mangled)[0] == '_' && (*mangled)[1] == '_') 3076169695Skan { 3077169695Skan string_prepend (declp, "::"); 3078169695Skan (*mangled) += 2; 3079169695Skan } 3080169695Skan } 3081169695Skan string_append (declp, " virtual table"); 3082169695Skan } 3083169695Skan else 3084169695Skan { 3085169695Skan success = 0; 3086169695Skan } 3087169695Skan return (success); 3088169695Skan} 3089169695Skan 3090169695Skan/* 3091169695Skan 3092169695SkanLOCAL FUNCTION 3093169695Skan 3094169695Skan demangle_qualified -- demangle 'Q' qualified name strings 3095169695Skan 3096169695SkanSYNOPSIS 3097169695Skan 3098169695Skan static int 3099169695Skan demangle_qualified (struct work_stuff *, const char *mangled, 3100169695Skan string *result, int isfuncname, int append); 3101169695Skan 3102169695SkanDESCRIPTION 3103169695Skan 3104169695Skan Demangle a qualified name, such as "Q25Outer5Inner" which is 3105169695Skan the mangled form of "Outer::Inner". The demangled output is 3106169695Skan prepended or appended to the result string according to the 3107169695Skan state of the append flag. 3108169695Skan 3109169695Skan If isfuncname is nonzero, then the qualified name we are building 3110169695Skan is going to be used as a member function name, so if it is a 3111169695Skan constructor or destructor function, append an appropriate 3112169695Skan constructor or destructor name. I.E. for the above example, 3113169695Skan the result for use as a constructor is "Outer::Inner::Inner" 3114169695Skan and the result for use as a destructor is "Outer::Inner::~Inner". 3115169695Skan 3116169695SkanBUGS 3117169695Skan 3118169695Skan Numeric conversion is ASCII dependent (FIXME). 3119169695Skan 3120169695Skan */ 3121169695Skan 3122169695Skanstatic int 3123169695Skandemangle_qualified (struct work_stuff *work, const char **mangled, 3124169695Skan string *result, int isfuncname, int append) 3125169695Skan{ 3126169695Skan int qualifiers = 0; 3127169695Skan int success = 1; 3128169695Skan char num[2]; 3129169695Skan string temp; 3130169695Skan string last_name; 3131169695Skan int bindex = register_Btype (work); 3132169695Skan 3133169695Skan /* We only make use of ISFUNCNAME if the entity is a constructor or 3134169695Skan destructor. */ 3135169695Skan isfuncname = (isfuncname 3136169695Skan && ((work->constructor & 1) || (work->destructor & 1))); 3137169695Skan 3138169695Skan string_init (&temp); 3139169695Skan string_init (&last_name); 3140169695Skan 3141169695Skan if ((*mangled)[0] == 'K') 3142169695Skan { 3143169695Skan /* Squangling qualified name reuse */ 3144169695Skan int idx; 3145169695Skan (*mangled)++; 3146169695Skan idx = consume_count_with_underscores (mangled); 3147169695Skan if (idx == -1 || idx >= work -> numk) 3148169695Skan success = 0; 3149169695Skan else 3150169695Skan string_append (&temp, work -> ktypevec[idx]); 3151169695Skan } 3152169695Skan else 3153169695Skan switch ((*mangled)[1]) 3154169695Skan { 3155169695Skan case '_': 3156169695Skan /* GNU mangled name with more than 9 classes. The count is preceded 3157169695Skan by an underscore (to distinguish it from the <= 9 case) and followed 3158169695Skan by an underscore. */ 3159169695Skan (*mangled)++; 3160169695Skan qualifiers = consume_count_with_underscores (mangled); 3161169695Skan if (qualifiers == -1) 3162169695Skan success = 0; 3163169695Skan break; 3164169695Skan 3165169695Skan case '1': 3166169695Skan case '2': 3167169695Skan case '3': 3168169695Skan case '4': 3169169695Skan case '5': 3170169695Skan case '6': 3171169695Skan case '7': 3172169695Skan case '8': 3173169695Skan case '9': 3174169695Skan /* The count is in a single digit. */ 3175169695Skan num[0] = (*mangled)[1]; 3176169695Skan num[1] = '\0'; 3177169695Skan qualifiers = atoi (num); 3178169695Skan 3179169695Skan /* If there is an underscore after the digit, skip it. This is 3180169695Skan said to be for ARM-qualified names, but the ARM makes no 3181169695Skan mention of such an underscore. Perhaps cfront uses one. */ 3182169695Skan if ((*mangled)[2] == '_') 3183169695Skan { 3184169695Skan (*mangled)++; 3185169695Skan } 3186169695Skan (*mangled) += 2; 3187169695Skan break; 3188169695Skan 3189169695Skan case '0': 3190169695Skan default: 3191169695Skan success = 0; 3192169695Skan } 3193169695Skan 3194169695Skan if (!success) 3195169695Skan return success; 3196169695Skan 3197169695Skan /* Pick off the names and collect them in the temp buffer in the order 3198169695Skan in which they are found, separated by '::'. */ 3199169695Skan 3200169695Skan while (qualifiers-- > 0) 3201169695Skan { 3202169695Skan int remember_K = 1; 3203169695Skan string_clear (&last_name); 3204169695Skan 3205169695Skan if (*mangled[0] == '_') 3206169695Skan (*mangled)++; 3207169695Skan 3208169695Skan if (*mangled[0] == 't') 3209169695Skan { 3210169695Skan /* Here we always append to TEMP since we will want to use 3211169695Skan the template name without the template parameters as a 3212169695Skan constructor or destructor name. The appropriate 3213169695Skan (parameter-less) value is returned by demangle_template 3214169695Skan in LAST_NAME. We do not remember the template type here, 3215169695Skan in order to match the G++ mangling algorithm. */ 3216169695Skan success = demangle_template(work, mangled, &temp, 3217169695Skan &last_name, 1, 0); 3218169695Skan if (!success) 3219169695Skan break; 3220169695Skan } 3221169695Skan else if (*mangled[0] == 'K') 3222169695Skan { 3223169695Skan int idx; 3224169695Skan (*mangled)++; 3225169695Skan idx = consume_count_with_underscores (mangled); 3226169695Skan if (idx == -1 || idx >= work->numk) 3227169695Skan success = 0; 3228169695Skan else 3229169695Skan string_append (&temp, work->ktypevec[idx]); 3230169695Skan remember_K = 0; 3231169695Skan 3232169695Skan if (!success) break; 3233169695Skan } 3234169695Skan else 3235169695Skan { 3236169695Skan if (EDG_DEMANGLING) 3237169695Skan { 3238169695Skan int namelength; 3239169695Skan /* Now recursively demangle the qualifier 3240169695Skan * This is necessary to deal with templates in 3241169695Skan * mangling styles like EDG */ 3242169695Skan namelength = consume_count (mangled); 3243169695Skan if (namelength == -1) 3244169695Skan { 3245169695Skan success = 0; 3246169695Skan break; 3247169695Skan } 3248169695Skan recursively_demangle(work, mangled, &temp, namelength); 3249169695Skan } 3250169695Skan else 3251169695Skan { 3252169695Skan string_delete (&last_name); 3253169695Skan success = do_type (work, mangled, &last_name); 3254169695Skan if (!success) 3255169695Skan break; 3256169695Skan string_appends (&temp, &last_name); 3257169695Skan } 3258169695Skan } 3259169695Skan 3260169695Skan if (remember_K) 3261169695Skan remember_Ktype (work, temp.b, LEN_STRING (&temp)); 3262169695Skan 3263169695Skan if (qualifiers > 0) 3264169695Skan string_append (&temp, SCOPE_STRING (work)); 3265169695Skan } 3266169695Skan 3267169695Skan remember_Btype (work, temp.b, LEN_STRING (&temp), bindex); 3268169695Skan 3269169695Skan /* If we are using the result as a function name, we need to append 3270169695Skan the appropriate '::' separated constructor or destructor name. 3271169695Skan We do this here because this is the most convenient place, where 3272169695Skan we already have a pointer to the name and the length of the name. */ 3273169695Skan 3274169695Skan if (isfuncname) 3275169695Skan { 3276169695Skan string_append (&temp, SCOPE_STRING (work)); 3277169695Skan if (work -> destructor & 1) 3278169695Skan string_append (&temp, "~"); 3279169695Skan string_appends (&temp, &last_name); 3280169695Skan } 3281169695Skan 3282169695Skan /* Now either prepend the temp buffer to the result, or append it, 3283169695Skan depending upon the state of the append flag. */ 3284169695Skan 3285169695Skan if (append) 3286169695Skan string_appends (result, &temp); 3287169695Skan else 3288169695Skan { 3289169695Skan if (!STRING_EMPTY (result)) 3290169695Skan string_append (&temp, SCOPE_STRING (work)); 3291169695Skan string_prepends (result, &temp); 3292169695Skan } 3293169695Skan 3294169695Skan string_delete (&last_name); 3295169695Skan string_delete (&temp); 3296169695Skan return (success); 3297169695Skan} 3298169695Skan 3299169695Skan/* 3300169695Skan 3301169695SkanLOCAL FUNCTION 3302169695Skan 3303169695Skan get_count -- convert an ascii count to integer, consuming tokens 3304169695Skan 3305169695SkanSYNOPSIS 3306169695Skan 3307169695Skan static int 3308169695Skan get_count (const char **type, int *count) 3309169695Skan 3310169695SkanDESCRIPTION 3311169695Skan 3312169695Skan Assume that *type points at a count in a mangled name; set 3313169695Skan *count to its value, and set *type to the next character after 3314169695Skan the count. There are some weird rules in effect here. 3315169695Skan 3316169695Skan If *type does not point at a string of digits, return zero. 3317169695Skan 3318169695Skan If *type points at a string of digits followed by an 3319169695Skan underscore, set *count to their value as an integer, advance 3320169695Skan *type to point *after the underscore, and return 1. 3321169695Skan 3322169695Skan If *type points at a string of digits not followed by an 3323169695Skan underscore, consume only the first digit. Set *count to its 3324169695Skan value as an integer, leave *type pointing after that digit, 3325169695Skan and return 1. 3326169695Skan 3327169695Skan The excuse for this odd behavior: in the ARM and HP demangling 3328169695Skan styles, a type can be followed by a repeat count of the form 3329169695Skan `Nxy', where: 3330169695Skan 3331169695Skan `x' is a single digit specifying how many additional copies 3332169695Skan of the type to append to the argument list, and 3333169695Skan 3334169695Skan `y' is one or more digits, specifying the zero-based index of 3335169695Skan the first repeated argument in the list. Yes, as you're 3336169695Skan unmangling the name you can figure this out yourself, but 3337169695Skan it's there anyway. 3338169695Skan 3339169695Skan So, for example, in `bar__3fooFPiN51', the first argument is a 3340169695Skan pointer to an integer (`Pi'), and then the next five arguments 3341169695Skan are the same (`N5'), and the first repeat is the function's 3342169695Skan second argument (`1'). 3343169695Skan*/ 3344169695Skan 3345169695Skanstatic int 3346169695Skanget_count (const char **type, int *count) 3347169695Skan{ 3348169695Skan const char *p; 3349169695Skan int n; 3350169695Skan 3351169695Skan if (!ISDIGIT ((unsigned char)**type)) 3352169695Skan return (0); 3353169695Skan else 3354169695Skan { 3355169695Skan *count = **type - '0'; 3356169695Skan (*type)++; 3357169695Skan if (ISDIGIT ((unsigned char)**type)) 3358169695Skan { 3359169695Skan p = *type; 3360169695Skan n = *count; 3361169695Skan do 3362169695Skan { 3363169695Skan n *= 10; 3364169695Skan n += *p - '0'; 3365169695Skan p++; 3366169695Skan } 3367169695Skan while (ISDIGIT ((unsigned char)*p)); 3368169695Skan if (*p == '_') 3369169695Skan { 3370169695Skan *type = p + 1; 3371169695Skan *count = n; 3372169695Skan } 3373169695Skan } 3374169695Skan } 3375169695Skan return (1); 3376169695Skan} 3377169695Skan 3378169695Skan/* RESULT will be initialised here; it will be freed on failure. The 3379169695Skan value returned is really a type_kind_t. */ 3380169695Skan 3381169695Skanstatic int 3382169695Skando_type (struct work_stuff *work, const char **mangled, string *result) 3383169695Skan{ 3384169695Skan int n; 3385169695Skan int done; 3386169695Skan int success; 3387169695Skan string decl; 3388169695Skan const char *remembered_type; 3389169695Skan int type_quals; 3390169695Skan type_kind_t tk = tk_none; 3391169695Skan 3392169695Skan string_init (&decl); 3393169695Skan string_init (result); 3394169695Skan 3395169695Skan done = 0; 3396169695Skan success = 1; 3397169695Skan while (success && !done) 3398169695Skan { 3399169695Skan int member; 3400169695Skan switch (**mangled) 3401169695Skan { 3402169695Skan 3403169695Skan /* A pointer type */ 3404169695Skan case 'P': 3405169695Skan case 'p': 3406169695Skan (*mangled)++; 3407169695Skan if (! (work -> options & DMGL_JAVA)) 3408169695Skan string_prepend (&decl, "*"); 3409169695Skan if (tk == tk_none) 3410169695Skan tk = tk_pointer; 3411169695Skan break; 3412169695Skan 3413169695Skan /* A reference type */ 3414169695Skan case 'R': 3415169695Skan (*mangled)++; 3416169695Skan string_prepend (&decl, "&"); 3417169695Skan if (tk == tk_none) 3418169695Skan tk = tk_reference; 3419169695Skan break; 3420169695Skan 3421169695Skan /* An array */ 3422169695Skan case 'A': 3423169695Skan { 3424169695Skan ++(*mangled); 3425169695Skan if (!STRING_EMPTY (&decl) 3426169695Skan && (decl.b[0] == '*' || decl.b[0] == '&')) 3427169695Skan { 3428169695Skan string_prepend (&decl, "("); 3429169695Skan string_append (&decl, ")"); 3430169695Skan } 3431169695Skan string_append (&decl, "["); 3432169695Skan if (**mangled != '_') 3433169695Skan success = demangle_template_value_parm (work, mangled, &decl, 3434169695Skan tk_integral); 3435169695Skan if (**mangled == '_') 3436169695Skan ++(*mangled); 3437169695Skan string_append (&decl, "]"); 3438169695Skan break; 3439169695Skan } 3440169695Skan 3441169695Skan /* A back reference to a previously seen type */ 3442169695Skan case 'T': 3443169695Skan (*mangled)++; 3444169695Skan if (!get_count (mangled, &n) || n >= work -> ntypes) 3445169695Skan { 3446169695Skan success = 0; 3447169695Skan } 3448169695Skan else 3449169695Skan { 3450169695Skan remembered_type = work -> typevec[n]; 3451169695Skan mangled = &remembered_type; 3452169695Skan } 3453169695Skan break; 3454169695Skan 3455169695Skan /* A function */ 3456169695Skan case 'F': 3457169695Skan (*mangled)++; 3458169695Skan if (!STRING_EMPTY (&decl) 3459169695Skan && (decl.b[0] == '*' || decl.b[0] == '&')) 3460169695Skan { 3461169695Skan string_prepend (&decl, "("); 3462169695Skan string_append (&decl, ")"); 3463169695Skan } 3464169695Skan /* After picking off the function args, we expect to either find the 3465169695Skan function return type (preceded by an '_') or the end of the 3466169695Skan string. */ 3467169695Skan if (!demangle_nested_args (work, mangled, &decl) 3468169695Skan || (**mangled != '_' && **mangled != '\0')) 3469169695Skan { 3470169695Skan success = 0; 3471169695Skan break; 3472169695Skan } 3473169695Skan if (success && (**mangled == '_')) 3474169695Skan (*mangled)++; 3475169695Skan break; 3476169695Skan 3477169695Skan case 'M': 3478169695Skan case 'O': 3479169695Skan { 3480169695Skan type_quals = TYPE_UNQUALIFIED; 3481169695Skan 3482169695Skan member = **mangled == 'M'; 3483169695Skan (*mangled)++; 3484169695Skan 3485169695Skan string_append (&decl, ")"); 3486169695Skan 3487169695Skan /* We don't need to prepend `::' for a qualified name; 3488169695Skan demangle_qualified will do that for us. */ 3489169695Skan if (**mangled != 'Q') 3490169695Skan string_prepend (&decl, SCOPE_STRING (work)); 3491169695Skan 3492169695Skan if (ISDIGIT ((unsigned char)**mangled)) 3493169695Skan { 3494169695Skan n = consume_count (mangled); 3495169695Skan if (n == -1 3496169695Skan || (int) strlen (*mangled) < n) 3497169695Skan { 3498169695Skan success = 0; 3499169695Skan break; 3500169695Skan } 3501169695Skan string_prependn (&decl, *mangled, n); 3502169695Skan *mangled += n; 3503169695Skan } 3504169695Skan else if (**mangled == 'X' || **mangled == 'Y') 3505169695Skan { 3506169695Skan string temp; 3507169695Skan do_type (work, mangled, &temp); 3508169695Skan string_prepends (&decl, &temp); 3509169695Skan string_delete (&temp); 3510169695Skan } 3511169695Skan else if (**mangled == 't') 3512169695Skan { 3513169695Skan string temp; 3514169695Skan string_init (&temp); 3515169695Skan success = demangle_template (work, mangled, &temp, 3516169695Skan NULL, 1, 1); 3517169695Skan if (success) 3518169695Skan { 3519169695Skan string_prependn (&decl, temp.b, temp.p - temp.b); 3520169695Skan string_delete (&temp); 3521169695Skan } 3522169695Skan else 3523169695Skan break; 3524169695Skan } 3525169695Skan else if (**mangled == 'Q') 3526169695Skan { 3527169695Skan success = demangle_qualified (work, mangled, &decl, 3528169695Skan /*isfuncnam=*/0, 3529169695Skan /*append=*/0); 3530169695Skan if (!success) 3531169695Skan break; 3532169695Skan } 3533169695Skan else 3534169695Skan { 3535169695Skan success = 0; 3536169695Skan break; 3537169695Skan } 3538169695Skan 3539169695Skan string_prepend (&decl, "("); 3540169695Skan if (member) 3541169695Skan { 3542169695Skan switch (**mangled) 3543169695Skan { 3544169695Skan case 'C': 3545169695Skan case 'V': 3546169695Skan case 'u': 3547169695Skan type_quals |= code_for_qualifier (**mangled); 3548169695Skan (*mangled)++; 3549169695Skan break; 3550169695Skan 3551169695Skan default: 3552169695Skan break; 3553169695Skan } 3554169695Skan 3555169695Skan if (*(*mangled)++ != 'F') 3556169695Skan { 3557169695Skan success = 0; 3558169695Skan break; 3559169695Skan } 3560169695Skan } 3561169695Skan if ((member && !demangle_nested_args (work, mangled, &decl)) 3562169695Skan || **mangled != '_') 3563169695Skan { 3564169695Skan success = 0; 3565169695Skan break; 3566169695Skan } 3567169695Skan (*mangled)++; 3568169695Skan if (! PRINT_ANSI_QUALIFIERS) 3569169695Skan { 3570169695Skan break; 3571169695Skan } 3572169695Skan if (type_quals != TYPE_UNQUALIFIED) 3573169695Skan { 3574169695Skan APPEND_BLANK (&decl); 3575169695Skan string_append (&decl, qualifier_string (type_quals)); 3576169695Skan } 3577169695Skan break; 3578169695Skan } 3579169695Skan case 'G': 3580169695Skan (*mangled)++; 3581169695Skan break; 3582169695Skan 3583169695Skan case 'C': 3584169695Skan case 'V': 3585169695Skan case 'u': 3586169695Skan if (PRINT_ANSI_QUALIFIERS) 3587169695Skan { 3588169695Skan if (!STRING_EMPTY (&decl)) 3589169695Skan string_prepend (&decl, " "); 3590169695Skan 3591169695Skan string_prepend (&decl, demangle_qualifier (**mangled)); 3592169695Skan } 3593169695Skan (*mangled)++; 3594169695Skan break; 3595169695Skan /* 3596169695Skan } 3597169695Skan */ 3598169695Skan 3599169695Skan /* fall through */ 3600169695Skan default: 3601169695Skan done = 1; 3602169695Skan break; 3603169695Skan } 3604169695Skan } 3605169695Skan 3606169695Skan if (success) switch (**mangled) 3607169695Skan { 3608169695Skan /* A qualified name, such as "Outer::Inner". */ 3609169695Skan case 'Q': 3610169695Skan case 'K': 3611169695Skan { 3612169695Skan success = demangle_qualified (work, mangled, result, 0, 1); 3613169695Skan break; 3614169695Skan } 3615169695Skan 3616169695Skan /* A back reference to a previously seen squangled type */ 3617169695Skan case 'B': 3618169695Skan (*mangled)++; 3619169695Skan if (!get_count (mangled, &n) || n >= work -> numb) 3620169695Skan success = 0; 3621169695Skan else 3622169695Skan string_append (result, work->btypevec[n]); 3623169695Skan break; 3624169695Skan 3625169695Skan case 'X': 3626169695Skan case 'Y': 3627169695Skan /* A template parm. We substitute the corresponding argument. */ 3628169695Skan { 3629169695Skan int idx; 3630169695Skan 3631169695Skan (*mangled)++; 3632169695Skan idx = consume_count_with_underscores (mangled); 3633169695Skan 3634169695Skan if (idx == -1 3635169695Skan || (work->tmpl_argvec && idx >= work->ntmpl_args) 3636169695Skan || consume_count_with_underscores (mangled) == -1) 3637169695Skan { 3638169695Skan success = 0; 3639169695Skan break; 3640169695Skan } 3641169695Skan 3642169695Skan if (work->tmpl_argvec) 3643169695Skan string_append (result, work->tmpl_argvec[idx]); 3644169695Skan else 3645169695Skan string_append_template_idx (result, idx); 3646169695Skan 3647169695Skan success = 1; 3648169695Skan } 3649169695Skan break; 3650169695Skan 3651169695Skan default: 3652169695Skan success = demangle_fund_type (work, mangled, result); 3653169695Skan if (tk == tk_none) 3654169695Skan tk = (type_kind_t) success; 3655169695Skan break; 3656169695Skan } 3657169695Skan 3658169695Skan if (success) 3659169695Skan { 3660169695Skan if (!STRING_EMPTY (&decl)) 3661169695Skan { 3662169695Skan string_append (result, " "); 3663169695Skan string_appends (result, &decl); 3664169695Skan } 3665169695Skan } 3666169695Skan else 3667169695Skan string_delete (result); 3668169695Skan string_delete (&decl); 3669169695Skan 3670169695Skan if (success) 3671169695Skan /* Assume an integral type, if we're not sure. */ 3672169695Skan return (int) ((tk == tk_none) ? tk_integral : tk); 3673169695Skan else 3674169695Skan return 0; 3675169695Skan} 3676169695Skan 3677169695Skan/* Given a pointer to a type string that represents a fundamental type 3678169695Skan argument (int, long, unsigned int, etc) in TYPE, a pointer to the 3679169695Skan string in which the demangled output is being built in RESULT, and 3680169695Skan the WORK structure, decode the types and add them to the result. 3681169695Skan 3682169695Skan For example: 3683169695Skan 3684169695Skan "Ci" => "const int" 3685169695Skan "Sl" => "signed long" 3686169695Skan "CUs" => "const unsigned short" 3687169695Skan 3688169695Skan The value returned is really a type_kind_t. */ 3689169695Skan 3690169695Skanstatic int 3691169695Skandemangle_fund_type (struct work_stuff *work, 3692169695Skan const char **mangled, string *result) 3693169695Skan{ 3694169695Skan int done = 0; 3695169695Skan int success = 1; 3696169695Skan char buf[INTBUF_SIZE + 5 /* 'int%u_t' */]; 3697169695Skan unsigned int dec = 0; 3698169695Skan type_kind_t tk = tk_integral; 3699169695Skan 3700169695Skan /* First pick off any type qualifiers. There can be more than one. */ 3701169695Skan 3702169695Skan while (!done) 3703169695Skan { 3704169695Skan switch (**mangled) 3705169695Skan { 3706169695Skan case 'C': 3707169695Skan case 'V': 3708169695Skan case 'u': 3709169695Skan if (PRINT_ANSI_QUALIFIERS) 3710169695Skan { 3711169695Skan if (!STRING_EMPTY (result)) 3712169695Skan string_prepend (result, " "); 3713169695Skan string_prepend (result, demangle_qualifier (**mangled)); 3714169695Skan } 3715169695Skan (*mangled)++; 3716169695Skan break; 3717169695Skan case 'U': 3718169695Skan (*mangled)++; 3719169695Skan APPEND_BLANK (result); 3720169695Skan string_append (result, "unsigned"); 3721169695Skan break; 3722169695Skan case 'S': /* signed char only */ 3723169695Skan (*mangled)++; 3724169695Skan APPEND_BLANK (result); 3725169695Skan string_append (result, "signed"); 3726169695Skan break; 3727169695Skan case 'J': 3728169695Skan (*mangled)++; 3729169695Skan APPEND_BLANK (result); 3730169695Skan string_append (result, "__complex"); 3731169695Skan break; 3732169695Skan default: 3733169695Skan done = 1; 3734169695Skan break; 3735169695Skan } 3736169695Skan } 3737169695Skan 3738169695Skan /* Now pick off the fundamental type. There can be only one. */ 3739169695Skan 3740169695Skan switch (**mangled) 3741169695Skan { 3742169695Skan case '\0': 3743169695Skan case '_': 3744169695Skan break; 3745169695Skan case 'v': 3746169695Skan (*mangled)++; 3747169695Skan APPEND_BLANK (result); 3748169695Skan string_append (result, "void"); 3749169695Skan break; 3750169695Skan case 'x': 3751169695Skan (*mangled)++; 3752169695Skan APPEND_BLANK (result); 3753169695Skan string_append (result, "long long"); 3754169695Skan break; 3755169695Skan case 'l': 3756169695Skan (*mangled)++; 3757169695Skan APPEND_BLANK (result); 3758169695Skan string_append (result, "long"); 3759169695Skan break; 3760169695Skan case 'i': 3761169695Skan (*mangled)++; 3762169695Skan APPEND_BLANK (result); 3763169695Skan string_append (result, "int"); 3764169695Skan break; 3765169695Skan case 's': 3766169695Skan (*mangled)++; 3767169695Skan APPEND_BLANK (result); 3768169695Skan string_append (result, "short"); 3769169695Skan break; 3770169695Skan case 'b': 3771169695Skan (*mangled)++; 3772169695Skan APPEND_BLANK (result); 3773169695Skan string_append (result, "bool"); 3774169695Skan tk = tk_bool; 3775169695Skan break; 3776169695Skan case 'c': 3777169695Skan (*mangled)++; 3778169695Skan APPEND_BLANK (result); 3779169695Skan string_append (result, "char"); 3780169695Skan tk = tk_char; 3781169695Skan break; 3782169695Skan case 'w': 3783169695Skan (*mangled)++; 3784169695Skan APPEND_BLANK (result); 3785169695Skan string_append (result, "wchar_t"); 3786169695Skan tk = tk_char; 3787169695Skan break; 3788169695Skan case 'r': 3789169695Skan (*mangled)++; 3790169695Skan APPEND_BLANK (result); 3791169695Skan string_append (result, "long double"); 3792169695Skan tk = tk_real; 3793169695Skan break; 3794169695Skan case 'd': 3795169695Skan (*mangled)++; 3796169695Skan APPEND_BLANK (result); 3797169695Skan string_append (result, "double"); 3798169695Skan tk = tk_real; 3799169695Skan break; 3800169695Skan case 'f': 3801169695Skan (*mangled)++; 3802169695Skan APPEND_BLANK (result); 3803169695Skan string_append (result, "float"); 3804169695Skan tk = tk_real; 3805169695Skan break; 3806169695Skan case 'G': 3807169695Skan (*mangled)++; 3808169695Skan if (!ISDIGIT ((unsigned char)**mangled)) 3809169695Skan { 3810169695Skan success = 0; 3811169695Skan break; 3812169695Skan } 3813169695Skan case 'I': 3814169695Skan (*mangled)++; 3815169695Skan if (**mangled == '_') 3816169695Skan { 3817169695Skan int i; 3818169695Skan (*mangled)++; 3819169695Skan for (i = 0; 3820169695Skan i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_'; 3821169695Skan (*mangled)++, i++) 3822169695Skan buf[i] = **mangled; 3823169695Skan if (**mangled != '_') 3824169695Skan { 3825169695Skan success = 0; 3826169695Skan break; 3827169695Skan } 3828169695Skan buf[i] = '\0'; 3829169695Skan (*mangled)++; 3830169695Skan } 3831169695Skan else 3832169695Skan { 3833169695Skan strncpy (buf, *mangled, 2); 3834169695Skan buf[2] = '\0'; 3835169695Skan *mangled += min (strlen (*mangled), 2); 3836169695Skan } 3837169695Skan sscanf (buf, "%x", &dec); 3838169695Skan sprintf (buf, "int%u_t", dec); 3839169695Skan APPEND_BLANK (result); 3840169695Skan string_append (result, buf); 3841169695Skan break; 3842169695Skan 3843169695Skan /* fall through */ 3844169695Skan /* An explicit type, such as "6mytype" or "7integer" */ 3845169695Skan case '0': 3846169695Skan case '1': 3847169695Skan case '2': 3848169695Skan case '3': 3849169695Skan case '4': 3850169695Skan case '5': 3851169695Skan case '6': 3852169695Skan case '7': 3853169695Skan case '8': 3854169695Skan case '9': 3855169695Skan { 3856169695Skan int bindex = register_Btype (work); 3857169695Skan string btype; 3858169695Skan string_init (&btype); 3859169695Skan if (demangle_class_name (work, mangled, &btype)) { 3860169695Skan remember_Btype (work, btype.b, LEN_STRING (&btype), bindex); 3861169695Skan APPEND_BLANK (result); 3862169695Skan string_appends (result, &btype); 3863169695Skan } 3864169695Skan else 3865169695Skan success = 0; 3866169695Skan string_delete (&btype); 3867169695Skan break; 3868169695Skan } 3869169695Skan case 't': 3870169695Skan { 3871169695Skan string btype; 3872169695Skan string_init (&btype); 3873169695Skan success = demangle_template (work, mangled, &btype, 0, 1, 1); 3874169695Skan string_appends (result, &btype); 3875169695Skan string_delete (&btype); 3876169695Skan break; 3877169695Skan } 3878169695Skan default: 3879169695Skan success = 0; 3880169695Skan break; 3881169695Skan } 3882169695Skan 3883169695Skan return success ? ((int) tk) : 0; 3884169695Skan} 3885169695Skan 3886169695Skan 3887169695Skan/* Handle a template's value parameter for HP aCC (extension from ARM) 3888169695Skan **mangled points to 'S' or 'U' */ 3889169695Skan 3890169695Skanstatic int 3891169695Skando_hpacc_template_const_value (struct work_stuff *work ATTRIBUTE_UNUSED, 3892169695Skan const char **mangled, string *result) 3893169695Skan{ 3894169695Skan int unsigned_const; 3895169695Skan 3896169695Skan if (**mangled != 'U' && **mangled != 'S') 3897169695Skan return 0; 3898169695Skan 3899169695Skan unsigned_const = (**mangled == 'U'); 3900169695Skan 3901169695Skan (*mangled)++; 3902169695Skan 3903169695Skan switch (**mangled) 3904169695Skan { 3905169695Skan case 'N': 3906169695Skan string_append (result, "-"); 3907169695Skan /* fall through */ 3908169695Skan case 'P': 3909169695Skan (*mangled)++; 3910169695Skan break; 3911169695Skan case 'M': 3912169695Skan /* special case for -2^31 */ 3913169695Skan string_append (result, "-2147483648"); 3914169695Skan (*mangled)++; 3915169695Skan return 1; 3916169695Skan default: 3917169695Skan return 0; 3918169695Skan } 3919169695Skan 3920169695Skan /* We have to be looking at an integer now */ 3921169695Skan if (!(ISDIGIT ((unsigned char)**mangled))) 3922169695Skan return 0; 3923169695Skan 3924169695Skan /* We only deal with integral values for template 3925169695Skan parameters -- so it's OK to look only for digits */ 3926169695Skan while (ISDIGIT ((unsigned char)**mangled)) 3927169695Skan { 3928169695Skan char_str[0] = **mangled; 3929169695Skan string_append (result, char_str); 3930169695Skan (*mangled)++; 3931169695Skan } 3932169695Skan 3933169695Skan if (unsigned_const) 3934169695Skan string_append (result, "U"); 3935169695Skan 3936169695Skan /* FIXME? Some day we may have 64-bit (or larger :-) ) constants 3937169695Skan with L or LL suffixes. pai/1997-09-03 */ 3938169695Skan 3939169695Skan return 1; /* success */ 3940169695Skan} 3941169695Skan 3942169695Skan/* Handle a template's literal parameter for HP aCC (extension from ARM) 3943169695Skan **mangled is pointing to the 'A' */ 3944169695Skan 3945169695Skanstatic int 3946169695Skando_hpacc_template_literal (struct work_stuff *work, const char **mangled, 3947169695Skan string *result) 3948169695Skan{ 3949169695Skan int literal_len = 0; 3950169695Skan char * recurse; 3951169695Skan char * recurse_dem; 3952169695Skan 3953169695Skan if (**mangled != 'A') 3954169695Skan return 0; 3955169695Skan 3956169695Skan (*mangled)++; 3957169695Skan 3958169695Skan literal_len = consume_count (mangled); 3959169695Skan 3960169695Skan if (literal_len <= 0) 3961169695Skan return 0; 3962169695Skan 3963169695Skan /* Literal parameters are names of arrays, functions, etc. and the 3964169695Skan canonical representation uses the address operator */ 3965169695Skan string_append (result, "&"); 3966169695Skan 3967169695Skan /* Now recursively demangle the literal name */ 3968169695Skan recurse = XNEWVEC (char, literal_len + 1); 3969169695Skan memcpy (recurse, *mangled, literal_len); 3970169695Skan recurse[literal_len] = '\000'; 3971169695Skan 3972169695Skan recurse_dem = cplus_demangle (recurse, work->options); 3973169695Skan 3974169695Skan if (recurse_dem) 3975169695Skan { 3976169695Skan string_append (result, recurse_dem); 3977169695Skan free (recurse_dem); 3978169695Skan } 3979169695Skan else 3980169695Skan { 3981169695Skan string_appendn (result, *mangled, literal_len); 3982169695Skan } 3983169695Skan (*mangled) += literal_len; 3984169695Skan free (recurse); 3985169695Skan 3986169695Skan return 1; 3987169695Skan} 3988169695Skan 3989169695Skanstatic int 3990169695Skansnarf_numeric_literal (const char **args, string *arg) 3991169695Skan{ 3992169695Skan if (**args == '-') 3993169695Skan { 3994169695Skan char_str[0] = '-'; 3995169695Skan string_append (arg, char_str); 3996169695Skan (*args)++; 3997169695Skan } 3998169695Skan else if (**args == '+') 3999169695Skan (*args)++; 4000169695Skan 4001169695Skan if (!ISDIGIT ((unsigned char)**args)) 4002169695Skan return 0; 4003169695Skan 4004169695Skan while (ISDIGIT ((unsigned char)**args)) 4005169695Skan { 4006169695Skan char_str[0] = **args; 4007169695Skan string_append (arg, char_str); 4008169695Skan (*args)++; 4009169695Skan } 4010169695Skan 4011169695Skan return 1; 4012169695Skan} 4013169695Skan 4014169695Skan/* Demangle the next argument, given by MANGLED into RESULT, which 4015169695Skan *should be an uninitialized* string. It will be initialized here, 4016169695Skan and free'd should anything go wrong. */ 4017169695Skan 4018169695Skanstatic int 4019169695Skando_arg (struct work_stuff *work, const char **mangled, string *result) 4020169695Skan{ 4021169695Skan /* Remember where we started so that we can record the type, for 4022169695Skan non-squangling type remembering. */ 4023169695Skan const char *start = *mangled; 4024169695Skan 4025169695Skan string_init (result); 4026169695Skan 4027169695Skan if (work->nrepeats > 0) 4028169695Skan { 4029169695Skan --work->nrepeats; 4030169695Skan 4031169695Skan if (work->previous_argument == 0) 4032169695Skan return 0; 4033169695Skan 4034169695Skan /* We want to reissue the previous type in this argument list. */ 4035169695Skan string_appends (result, work->previous_argument); 4036169695Skan return 1; 4037169695Skan } 4038169695Skan 4039169695Skan if (**mangled == 'n') 4040169695Skan { 4041169695Skan /* A squangling-style repeat. */ 4042169695Skan (*mangled)++; 4043169695Skan work->nrepeats = consume_count(mangled); 4044169695Skan 4045169695Skan if (work->nrepeats <= 0) 4046169695Skan /* This was not a repeat count after all. */ 4047169695Skan return 0; 4048169695Skan 4049169695Skan if (work->nrepeats > 9) 4050169695Skan { 4051169695Skan if (**mangled != '_') 4052169695Skan /* The repeat count should be followed by an '_' in this 4053169695Skan case. */ 4054169695Skan return 0; 4055169695Skan else 4056169695Skan (*mangled)++; 4057169695Skan } 4058169695Skan 4059169695Skan /* Now, the repeat is all set up. */ 4060169695Skan return do_arg (work, mangled, result); 4061169695Skan } 4062169695Skan 4063169695Skan /* Save the result in WORK->previous_argument so that we can find it 4064169695Skan if it's repeated. Note that saving START is not good enough: we 4065169695Skan do not want to add additional types to the back-referenceable 4066169695Skan type vector when processing a repeated type. */ 4067169695Skan if (work->previous_argument) 4068169695Skan string_delete (work->previous_argument); 4069169695Skan else 4070169695Skan work->previous_argument = XNEW (string); 4071169695Skan 4072169695Skan if (!do_type (work, mangled, work->previous_argument)) 4073169695Skan return 0; 4074169695Skan 4075169695Skan string_appends (result, work->previous_argument); 4076169695Skan 4077169695Skan remember_type (work, start, *mangled - start); 4078169695Skan return 1; 4079169695Skan} 4080169695Skan 4081169695Skanstatic void 4082169695Skanremember_type (struct work_stuff *work, const char *start, int len) 4083169695Skan{ 4084169695Skan char *tem; 4085169695Skan 4086169695Skan if (work->forgetting_types) 4087169695Skan return; 4088169695Skan 4089169695Skan if (work -> ntypes >= work -> typevec_size) 4090169695Skan { 4091169695Skan if (work -> typevec_size == 0) 4092169695Skan { 4093169695Skan work -> typevec_size = 3; 4094169695Skan work -> typevec = XNEWVEC (char *, work->typevec_size); 4095169695Skan } 4096169695Skan else 4097169695Skan { 4098169695Skan work -> typevec_size *= 2; 4099169695Skan work -> typevec 4100169695Skan = XRESIZEVEC (char *, work->typevec, work->typevec_size); 4101169695Skan } 4102169695Skan } 4103169695Skan tem = XNEWVEC (char, len + 1); 4104169695Skan memcpy (tem, start, len); 4105169695Skan tem[len] = '\0'; 4106169695Skan work -> typevec[work -> ntypes++] = tem; 4107169695Skan} 4108169695Skan 4109169695Skan 4110169695Skan/* Remember a K type class qualifier. */ 4111169695Skanstatic void 4112169695Skanremember_Ktype (struct work_stuff *work, const char *start, int len) 4113169695Skan{ 4114169695Skan char *tem; 4115169695Skan 4116169695Skan if (work -> numk >= work -> ksize) 4117169695Skan { 4118169695Skan if (work -> ksize == 0) 4119169695Skan { 4120169695Skan work -> ksize = 5; 4121169695Skan work -> ktypevec = XNEWVEC (char *, work->ksize); 4122169695Skan } 4123169695Skan else 4124169695Skan { 4125169695Skan work -> ksize *= 2; 4126169695Skan work -> ktypevec 4127169695Skan = XRESIZEVEC (char *, work->ktypevec, work->ksize); 4128169695Skan } 4129169695Skan } 4130169695Skan tem = XNEWVEC (char, len + 1); 4131169695Skan memcpy (tem, start, len); 4132169695Skan tem[len] = '\0'; 4133169695Skan work -> ktypevec[work -> numk++] = tem; 4134169695Skan} 4135169695Skan 4136169695Skan/* Register a B code, and get an index for it. B codes are registered 4137169695Skan as they are seen, rather than as they are completed, so map<temp<char> > 4138169695Skan registers map<temp<char> > as B0, and temp<char> as B1 */ 4139169695Skan 4140169695Skanstatic int 4141169695Skanregister_Btype (struct work_stuff *work) 4142169695Skan{ 4143169695Skan int ret; 4144169695Skan 4145169695Skan if (work -> numb >= work -> bsize) 4146169695Skan { 4147169695Skan if (work -> bsize == 0) 4148169695Skan { 4149169695Skan work -> bsize = 5; 4150169695Skan work -> btypevec = XNEWVEC (char *, work->bsize); 4151169695Skan } 4152169695Skan else 4153169695Skan { 4154169695Skan work -> bsize *= 2; 4155169695Skan work -> btypevec 4156169695Skan = XRESIZEVEC (char *, work->btypevec, work->bsize); 4157169695Skan } 4158169695Skan } 4159169695Skan ret = work -> numb++; 4160169695Skan work -> btypevec[ret] = NULL; 4161169695Skan return(ret); 4162169695Skan} 4163169695Skan 4164169695Skan/* Store a value into a previously registered B code type. */ 4165169695Skan 4166169695Skanstatic void 4167169695Skanremember_Btype (struct work_stuff *work, const char *start, 4168169695Skan int len, int index) 4169169695Skan{ 4170169695Skan char *tem; 4171169695Skan 4172169695Skan tem = XNEWVEC (char, len + 1); 4173169695Skan memcpy (tem, start, len); 4174169695Skan tem[len] = '\0'; 4175169695Skan work -> btypevec[index] = tem; 4176169695Skan} 4177169695Skan 4178169695Skan/* Lose all the info related to B and K type codes. */ 4179169695Skanstatic void 4180169695Skanforget_B_and_K_types (struct work_stuff *work) 4181169695Skan{ 4182169695Skan int i; 4183169695Skan 4184169695Skan while (work -> numk > 0) 4185169695Skan { 4186169695Skan i = --(work -> numk); 4187169695Skan if (work -> ktypevec[i] != NULL) 4188169695Skan { 4189169695Skan free (work -> ktypevec[i]); 4190169695Skan work -> ktypevec[i] = NULL; 4191169695Skan } 4192169695Skan } 4193169695Skan 4194169695Skan while (work -> numb > 0) 4195169695Skan { 4196169695Skan i = --(work -> numb); 4197169695Skan if (work -> btypevec[i] != NULL) 4198169695Skan { 4199169695Skan free (work -> btypevec[i]); 4200169695Skan work -> btypevec[i] = NULL; 4201169695Skan } 4202169695Skan } 4203169695Skan} 4204169695Skan/* Forget the remembered types, but not the type vector itself. */ 4205169695Skan 4206169695Skanstatic void 4207169695Skanforget_types (struct work_stuff *work) 4208169695Skan{ 4209169695Skan int i; 4210169695Skan 4211169695Skan while (work -> ntypes > 0) 4212169695Skan { 4213169695Skan i = --(work -> ntypes); 4214169695Skan if (work -> typevec[i] != NULL) 4215169695Skan { 4216169695Skan free (work -> typevec[i]); 4217169695Skan work -> typevec[i] = NULL; 4218169695Skan } 4219169695Skan } 4220169695Skan} 4221169695Skan 4222169695Skan/* Process the argument list part of the signature, after any class spec 4223169695Skan has been consumed, as well as the first 'F' character (if any). For 4224169695Skan example: 4225169695Skan 4226169695Skan "__als__3fooRT0" => process "RT0" 4227169695Skan "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i" 4228169695Skan 4229169695Skan DECLP must be already initialised, usually non-empty. It won't be freed 4230169695Skan on failure. 4231169695Skan 4232169695Skan Note that g++ differs significantly from ARM and lucid style mangling 4233169695Skan with regards to references to previously seen types. For example, given 4234169695Skan the source fragment: 4235169695Skan 4236169695Skan class foo { 4237169695Skan public: 4238169695Skan foo::foo (int, foo &ia, int, foo &ib, int, foo &ic); 4239169695Skan }; 4240169695Skan 4241169695Skan foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } 4242169695Skan void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } 4243169695Skan 4244169695Skan g++ produces the names: 4245169695Skan 4246169695Skan __3fooiRT0iT2iT2 4247169695Skan foo__FiR3fooiT1iT1 4248169695Skan 4249169695Skan while lcc (and presumably other ARM style compilers as well) produces: 4250169695Skan 4251169695Skan foo__FiR3fooT1T2T1T2 4252169695Skan __ct__3fooFiR3fooT1T2T1T2 4253169695Skan 4254169695Skan Note that g++ bases its type numbers starting at zero and counts all 4255169695Skan previously seen types, while lucid/ARM bases its type numbers starting 4256169695Skan at one and only considers types after it has seen the 'F' character 4257169695Skan indicating the start of the function args. For lucid/ARM style, we 4258169695Skan account for this difference by discarding any previously seen types when 4259169695Skan we see the 'F' character, and subtracting one from the type number 4260169695Skan reference. 4261169695Skan 4262169695Skan */ 4263169695Skan 4264169695Skanstatic int 4265169695Skandemangle_args (struct work_stuff *work, const char **mangled, 4266169695Skan string *declp) 4267169695Skan{ 4268169695Skan string arg; 4269169695Skan int need_comma = 0; 4270169695Skan int r; 4271169695Skan int t; 4272169695Skan const char *tem; 4273169695Skan char temptype; 4274169695Skan 4275169695Skan if (PRINT_ARG_TYPES) 4276169695Skan { 4277169695Skan string_append (declp, "("); 4278169695Skan if (**mangled == '\0') 4279169695Skan { 4280169695Skan string_append (declp, "void"); 4281169695Skan } 4282169695Skan } 4283169695Skan 4284169695Skan while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e') 4285169695Skan || work->nrepeats > 0) 4286169695Skan { 4287169695Skan if ((**mangled == 'N') || (**mangled == 'T')) 4288169695Skan { 4289169695Skan temptype = *(*mangled)++; 4290169695Skan 4291169695Skan if (temptype == 'N') 4292169695Skan { 4293169695Skan if (!get_count (mangled, &r)) 4294169695Skan { 4295169695Skan return (0); 4296169695Skan } 4297169695Skan } 4298169695Skan else 4299169695Skan { 4300169695Skan r = 1; 4301169695Skan } 4302169695Skan if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10) 4303169695Skan { 4304169695Skan /* If we have 10 or more types we might have more than a 1 digit 4305169695Skan index so we'll have to consume the whole count here. This 4306169695Skan will lose if the next thing is a type name preceded by a 4307169695Skan count but it's impossible to demangle that case properly 4308169695Skan anyway. Eg if we already have 12 types is T12Pc "(..., type1, 4309169695Skan Pc, ...)" or "(..., type12, char *, ...)" */ 4310169695Skan if ((t = consume_count(mangled)) <= 0) 4311169695Skan { 4312169695Skan return (0); 4313169695Skan } 4314169695Skan } 4315169695Skan else 4316169695Skan { 4317169695Skan if (!get_count (mangled, &t)) 4318169695Skan { 4319169695Skan return (0); 4320169695Skan } 4321169695Skan } 4322169695Skan if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) 4323169695Skan { 4324169695Skan t--; 4325169695Skan } 4326169695Skan /* Validate the type index. Protect against illegal indices from 4327169695Skan malformed type strings. */ 4328169695Skan if ((t < 0) || (t >= work -> ntypes)) 4329169695Skan { 4330169695Skan return (0); 4331169695Skan } 4332169695Skan while (work->nrepeats > 0 || --r >= 0) 4333169695Skan { 4334169695Skan tem = work -> typevec[t]; 4335169695Skan if (need_comma && PRINT_ARG_TYPES) 4336169695Skan { 4337169695Skan string_append (declp, ", "); 4338169695Skan } 4339169695Skan if (!do_arg (work, &tem, &arg)) 4340169695Skan { 4341169695Skan return (0); 4342169695Skan } 4343169695Skan if (PRINT_ARG_TYPES) 4344169695Skan { 4345169695Skan string_appends (declp, &arg); 4346169695Skan } 4347169695Skan string_delete (&arg); 4348169695Skan need_comma = 1; 4349169695Skan } 4350169695Skan } 4351169695Skan else 4352169695Skan { 4353169695Skan if (need_comma && PRINT_ARG_TYPES) 4354169695Skan string_append (declp, ", "); 4355169695Skan if (!do_arg (work, mangled, &arg)) 4356169695Skan return (0); 4357169695Skan if (PRINT_ARG_TYPES) 4358169695Skan string_appends (declp, &arg); 4359169695Skan string_delete (&arg); 4360169695Skan need_comma = 1; 4361169695Skan } 4362169695Skan } 4363169695Skan 4364169695Skan if (**mangled == 'e') 4365169695Skan { 4366169695Skan (*mangled)++; 4367169695Skan if (PRINT_ARG_TYPES) 4368169695Skan { 4369169695Skan if (need_comma) 4370169695Skan { 4371169695Skan string_append (declp, ","); 4372169695Skan } 4373169695Skan string_append (declp, "..."); 4374169695Skan } 4375169695Skan } 4376169695Skan 4377169695Skan if (PRINT_ARG_TYPES) 4378169695Skan { 4379169695Skan string_append (declp, ")"); 4380169695Skan } 4381169695Skan return (1); 4382169695Skan} 4383169695Skan 4384169695Skan/* Like demangle_args, but for demangling the argument lists of function 4385169695Skan and method pointers or references, not top-level declarations. */ 4386169695Skan 4387169695Skanstatic int 4388169695Skandemangle_nested_args (struct work_stuff *work, const char **mangled, 4389169695Skan string *declp) 4390169695Skan{ 4391169695Skan string* saved_previous_argument; 4392169695Skan int result; 4393169695Skan int saved_nrepeats; 4394169695Skan 4395169695Skan /* The G++ name-mangling algorithm does not remember types on nested 4396169695Skan argument lists, unless -fsquangling is used, and in that case the 4397169695Skan type vector updated by remember_type is not used. So, we turn 4398169695Skan off remembering of types here. */ 4399169695Skan ++work->forgetting_types; 4400169695Skan 4401169695Skan /* For the repeat codes used with -fsquangling, we must keep track of 4402169695Skan the last argument. */ 4403169695Skan saved_previous_argument = work->previous_argument; 4404169695Skan saved_nrepeats = work->nrepeats; 4405169695Skan work->previous_argument = 0; 4406169695Skan work->nrepeats = 0; 4407169695Skan 4408169695Skan /* Actually demangle the arguments. */ 4409169695Skan result = demangle_args (work, mangled, declp); 4410169695Skan 4411169695Skan /* Restore the previous_argument field. */ 4412169695Skan if (work->previous_argument) 4413169695Skan { 4414169695Skan string_delete (work->previous_argument); 4415169695Skan free ((char *) work->previous_argument); 4416169695Skan } 4417169695Skan work->previous_argument = saved_previous_argument; 4418169695Skan --work->forgetting_types; 4419169695Skan work->nrepeats = saved_nrepeats; 4420169695Skan 4421169695Skan return result; 4422169695Skan} 4423169695Skan 4424169695Skanstatic void 4425169695Skandemangle_function_name (struct work_stuff *work, const char **mangled, 4426169695Skan string *declp, const char *scan) 4427169695Skan{ 4428169695Skan size_t i; 4429169695Skan string type; 4430169695Skan const char *tem; 4431169695Skan 4432169695Skan string_appendn (declp, (*mangled), scan - (*mangled)); 4433169695Skan string_need (declp, 1); 4434169695Skan *(declp -> p) = '\0'; 4435169695Skan 4436169695Skan /* Consume the function name, including the "__" separating the name 4437169695Skan from the signature. We are guaranteed that SCAN points to the 4438169695Skan separator. */ 4439169695Skan 4440169695Skan (*mangled) = scan + 2; 4441169695Skan /* We may be looking at an instantiation of a template function: 4442169695Skan foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a 4443169695Skan following _F marks the start of the function arguments. Handle 4444169695Skan the template arguments first. */ 4445169695Skan 4446169695Skan if (HP_DEMANGLING && (**mangled == 'X')) 4447169695Skan { 4448169695Skan demangle_arm_hp_template (work, mangled, 0, declp); 4449169695Skan /* This leaves MANGLED pointing to the 'F' marking func args */ 4450169695Skan } 4451169695Skan 4452169695Skan if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) 4453169695Skan { 4454169695Skan 4455169695Skan /* See if we have an ARM style constructor or destructor operator. 4456169695Skan If so, then just record it, clear the decl, and return. 4457169695Skan We can't build the actual constructor/destructor decl until later, 4458169695Skan when we recover the class name from the signature. */ 4459169695Skan 4460169695Skan if (strcmp (declp -> b, "__ct") == 0) 4461169695Skan { 4462169695Skan work -> constructor += 1; 4463169695Skan string_clear (declp); 4464169695Skan return; 4465169695Skan } 4466169695Skan else if (strcmp (declp -> b, "__dt") == 0) 4467169695Skan { 4468169695Skan work -> destructor += 1; 4469169695Skan string_clear (declp); 4470169695Skan return; 4471169695Skan } 4472169695Skan } 4473169695Skan 4474169695Skan if (declp->p - declp->b >= 3 4475169695Skan && declp->b[0] == 'o' 4476169695Skan && declp->b[1] == 'p' 4477169695Skan && strchr (cplus_markers, declp->b[2]) != NULL) 4478169695Skan { 4479169695Skan /* see if it's an assignment expression */ 4480169695Skan if (declp->p - declp->b >= 10 /* op$assign_ */ 4481169695Skan && memcmp (declp->b + 3, "assign_", 7) == 0) 4482169695Skan { 4483169695Skan for (i = 0; i < ARRAY_SIZE (optable); i++) 4484169695Skan { 4485169695Skan int len = declp->p - declp->b - 10; 4486169695Skan if ((int) strlen (optable[i].in) == len 4487169695Skan && memcmp (optable[i].in, declp->b + 10, len) == 0) 4488169695Skan { 4489169695Skan string_clear (declp); 4490169695Skan string_append (declp, "operator"); 4491169695Skan string_append (declp, optable[i].out); 4492169695Skan string_append (declp, "="); 4493169695Skan break; 4494169695Skan } 4495169695Skan } 4496169695Skan } 4497169695Skan else 4498169695Skan { 4499169695Skan for (i = 0; i < ARRAY_SIZE (optable); i++) 4500169695Skan { 4501169695Skan int len = declp->p - declp->b - 3; 4502169695Skan if ((int) strlen (optable[i].in) == len 4503169695Skan && memcmp (optable[i].in, declp->b + 3, len) == 0) 4504169695Skan { 4505169695Skan string_clear (declp); 4506169695Skan string_append (declp, "operator"); 4507169695Skan string_append (declp, optable[i].out); 4508169695Skan break; 4509169695Skan } 4510169695Skan } 4511169695Skan } 4512169695Skan } 4513169695Skan else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0 4514169695Skan && strchr (cplus_markers, declp->b[4]) != NULL) 4515169695Skan { 4516169695Skan /* type conversion operator */ 4517169695Skan tem = declp->b + 5; 4518169695Skan if (do_type (work, &tem, &type)) 4519169695Skan { 4520169695Skan string_clear (declp); 4521169695Skan string_append (declp, "operator "); 4522169695Skan string_appends (declp, &type); 4523169695Skan string_delete (&type); 4524169695Skan } 4525169695Skan } 4526169695Skan else if (declp->b[0] == '_' && declp->b[1] == '_' 4527169695Skan && declp->b[2] == 'o' && declp->b[3] == 'p') 4528169695Skan { 4529169695Skan /* ANSI. */ 4530169695Skan /* type conversion operator. */ 4531169695Skan tem = declp->b + 4; 4532169695Skan if (do_type (work, &tem, &type)) 4533169695Skan { 4534169695Skan string_clear (declp); 4535169695Skan string_append (declp, "operator "); 4536169695Skan string_appends (declp, &type); 4537169695Skan string_delete (&type); 4538169695Skan } 4539169695Skan } 4540169695Skan else if (declp->b[0] == '_' && declp->b[1] == '_' 4541169695Skan && ISLOWER((unsigned char)declp->b[2]) 4542169695Skan && ISLOWER((unsigned char)declp->b[3])) 4543169695Skan { 4544169695Skan if (declp->b[4] == '\0') 4545169695Skan { 4546169695Skan /* Operator. */ 4547169695Skan for (i = 0; i < ARRAY_SIZE (optable); i++) 4548169695Skan { 4549169695Skan if (strlen (optable[i].in) == 2 4550169695Skan && memcmp (optable[i].in, declp->b + 2, 2) == 0) 4551169695Skan { 4552169695Skan string_clear (declp); 4553169695Skan string_append (declp, "operator"); 4554169695Skan string_append (declp, optable[i].out); 4555169695Skan break; 4556169695Skan } 4557169695Skan } 4558169695Skan } 4559169695Skan else 4560169695Skan { 4561169695Skan if (declp->b[2] == 'a' && declp->b[5] == '\0') 4562169695Skan { 4563169695Skan /* Assignment. */ 4564169695Skan for (i = 0; i < ARRAY_SIZE (optable); i++) 4565169695Skan { 4566169695Skan if (strlen (optable[i].in) == 3 4567169695Skan && memcmp (optable[i].in, declp->b + 2, 3) == 0) 4568169695Skan { 4569169695Skan string_clear (declp); 4570169695Skan string_append (declp, "operator"); 4571169695Skan string_append (declp, optable[i].out); 4572169695Skan break; 4573169695Skan } 4574169695Skan } 4575169695Skan } 4576169695Skan } 4577169695Skan } 4578169695Skan} 4579169695Skan 4580169695Skan/* a mini string-handling package */ 4581169695Skan 4582169695Skanstatic void 4583169695Skanstring_need (string *s, int n) 4584169695Skan{ 4585169695Skan int tem; 4586169695Skan 4587169695Skan if (s->b == NULL) 4588169695Skan { 4589169695Skan if (n < 32) 4590169695Skan { 4591169695Skan n = 32; 4592169695Skan } 4593169695Skan s->p = s->b = XNEWVEC (char, n); 4594169695Skan s->e = s->b + n; 4595169695Skan } 4596169695Skan else if (s->e - s->p < n) 4597169695Skan { 4598169695Skan tem = s->p - s->b; 4599169695Skan n += tem; 4600169695Skan n *= 2; 4601169695Skan s->b = XRESIZEVEC (char, s->b, n); 4602169695Skan s->p = s->b + tem; 4603169695Skan s->e = s->b + n; 4604169695Skan } 4605169695Skan} 4606169695Skan 4607169695Skanstatic void 4608169695Skanstring_delete (string *s) 4609169695Skan{ 4610169695Skan if (s->b != NULL) 4611169695Skan { 4612169695Skan free (s->b); 4613169695Skan s->b = s->e = s->p = NULL; 4614169695Skan } 4615169695Skan} 4616169695Skan 4617169695Skanstatic void 4618169695Skanstring_init (string *s) 4619169695Skan{ 4620169695Skan s->b = s->p = s->e = NULL; 4621169695Skan} 4622169695Skan 4623169695Skanstatic void 4624169695Skanstring_clear (string *s) 4625169695Skan{ 4626169695Skan s->p = s->b; 4627169695Skan} 4628169695Skan 4629169695Skan#if 0 4630169695Skan 4631169695Skanstatic int 4632169695Skanstring_empty (string *s) 4633169695Skan{ 4634169695Skan return (s->b == s->p); 4635169695Skan} 4636169695Skan 4637169695Skan#endif 4638169695Skan 4639169695Skanstatic void 4640169695Skanstring_append (string *p, const char *s) 4641169695Skan{ 4642169695Skan int n; 4643169695Skan if (s == NULL || *s == '\0') 4644169695Skan return; 4645169695Skan n = strlen (s); 4646169695Skan string_need (p, n); 4647169695Skan memcpy (p->p, s, n); 4648169695Skan p->p += n; 4649169695Skan} 4650169695Skan 4651169695Skanstatic void 4652169695Skanstring_appends (string *p, string *s) 4653169695Skan{ 4654169695Skan int n; 4655169695Skan 4656169695Skan if (s->b != s->p) 4657169695Skan { 4658169695Skan n = s->p - s->b; 4659169695Skan string_need (p, n); 4660169695Skan memcpy (p->p, s->b, n); 4661169695Skan p->p += n; 4662169695Skan } 4663169695Skan} 4664169695Skan 4665169695Skanstatic void 4666169695Skanstring_appendn (string *p, const char *s, int n) 4667169695Skan{ 4668169695Skan if (n != 0) 4669169695Skan { 4670169695Skan string_need (p, n); 4671169695Skan memcpy (p->p, s, n); 4672169695Skan p->p += n; 4673169695Skan } 4674169695Skan} 4675169695Skan 4676169695Skanstatic void 4677169695Skanstring_prepend (string *p, const char *s) 4678169695Skan{ 4679169695Skan if (s != NULL && *s != '\0') 4680169695Skan { 4681169695Skan string_prependn (p, s, strlen (s)); 4682169695Skan } 4683169695Skan} 4684169695Skan 4685169695Skanstatic void 4686169695Skanstring_prepends (string *p, string *s) 4687169695Skan{ 4688169695Skan if (s->b != s->p) 4689169695Skan { 4690169695Skan string_prependn (p, s->b, s->p - s->b); 4691169695Skan } 4692169695Skan} 4693169695Skan 4694169695Skanstatic void 4695169695Skanstring_prependn (string *p, const char *s, int n) 4696169695Skan{ 4697169695Skan char *q; 4698169695Skan 4699169695Skan if (n != 0) 4700169695Skan { 4701169695Skan string_need (p, n); 4702169695Skan for (q = p->p - 1; q >= p->b; q--) 4703169695Skan { 4704169695Skan q[n] = q[0]; 4705169695Skan } 4706169695Skan memcpy (p->b, s, n); 4707169695Skan p->p += n; 4708169695Skan } 4709169695Skan} 4710169695Skan 4711169695Skanstatic void 4712169695Skanstring_append_template_idx (string *s, int idx) 4713169695Skan{ 4714169695Skan char buf[INTBUF_SIZE + 1 /* 'T' */]; 4715169695Skan sprintf(buf, "T%d", idx); 4716169695Skan string_append (s, buf); 4717169695Skan} 4718