1 /* $MirOS: src/gnu/usr.bin/binutils/libiberty/cplus-dem.c,v 1.5 2008/11/08 23:03:46 tg Exp $ */
2 
3 /* Demangler for GNU C++
4    Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
5    2000, 2001, 2002, 2003, 2004, 2005
6    Free Software Foundation, Inc.
7    Written by James Clark (jjc@jclark.uucp)
8    Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
9    Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
10    API broken by Thorsten Glaser (tg@mirbsd.org)
11 
12 This file is part of the libiberty library.
13 Libiberty is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Library General Public
15 License as published by the Free Software Foundation; either
16 version 2 of the License, or (at your option) any later version.
17 
18 In addition to the permissions in the GNU Library General Public
19 License, the Free Software Foundation gives you unlimited permission
20 to link the compiled version of this file into combinations with other
21 programs, and to distribute those combinations without any restriction
22 coming from the use of this file.  (The Library Public License
23 restrictions do apply in other respects; for example, they cover
24 modification of the file, and distribution when not linked into a
25 combined executable.)
26 
27 Libiberty is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
30 Library General Public License for more details.
31 
32 You should have received a copy of the GNU Library General Public
33 License along with libiberty; see the file COPYING.LIB.  If
34 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
35 Boston, MA 02110-1301, USA.  */
36 
37 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
38 
39    This file imports xmalloc and xrealloc, which are like malloc and
40    realloc except that they generate a fatal error if there is no
41    available memory.  */
42 
43 /* This file lives in both GCC and libiberty.  When making changes, please
44    try not to break either.  */
45 
46 #ifdef HAVE_CONFIG_H
47 #include "config.h"
48 #endif
49 
50 __RCSID("$MirOS: src/gnu/usr.bin/binutils/libiberty/cplus-dem.c,v 1.5 2008/11/08 23:03:46 tg Exp $");
51 
52 #include "safe-ctype.h"
53 
54 #include <sys/types.h>
55 #include <string.h>
56 #include <stdio.h>
57 
58 #ifdef HAVE_STDLIB_H
59 #include <stdlib.h>
60 #else
61 char * malloc ();
62 char * realloc ();
63 #endif
64 
65 #include <demangle.h>
66 #undef CURRENT_DEMANGLING_STYLE
67 #define CURRENT_DEMANGLING_STYLE work->options
68 
69 #include "libiberty.h"
70 
71 static char *ada_demangle (const char *, int);
72 
73 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
74 
75 /* A value at least one greater than the maximum number of characters
76    that will be output when using the `%d' format with `printf'.  */
77 #define INTBUF_SIZE 32
78 
79 extern void fancy_abort (void) ATTRIBUTE_NORETURN;
80 
81 /* In order to allow a single demangler executable to demangle strings
82    using various common values of CPLUS_MARKER, as well as any specific
83    one set at compile time, we maintain a string containing all the
84    commonly used ones, and check to see if the marker we are looking for
85    is in that string.  CPLUS_MARKER is usually '$' on systems where the
86    assembler can deal with that.  Where the assembler can't, it's usually
87    '.' (but on many systems '.' is used for other things).  We put the
88    current defined CPLUS_MARKER first (which defaults to '$'), followed
89    by the next most common value, followed by an explicit '$' in case
90    the value of CPLUS_MARKER is not '$'.
91 
92    We could avoid this if we could just get g++ to tell us what the actual
93    cplus marker character is as part of the debug information, perhaps by
94    ensuring that it is the character that terminates the gcc<n>_compiled
95    marker symbol (FIXME).  */
96 
97 #if !defined (CPLUS_MARKER)
98 #define CPLUS_MARKER '$'
99 #endif
100 
101 enum demangling_styles current_demangling_style = auto_demangling;
102 
103 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
104 
105 static char char_str[2] = { '\000', '\000' };
106 
107 void
set_cplus_marker_for_demangling(int ch)108 set_cplus_marker_for_demangling (int ch)
109 {
110   cplus_markers[0] = ch;
111 }
112 
113 typedef struct string		/* Beware: these aren't required to be */
114 {				/*  '\0' terminated.  */
115   char *b;			/* pointer to start of string */
116   char *p;			/* pointer after last character */
117   char *e;			/* pointer after end of allocated space */
118 } string;
119 
120 /* Stuff that is shared between sub-routines.
121    Using a shared structure allows cplus_demangle to be reentrant.  */
122 
123 struct work_stuff
124 {
125   int options;
126   char **typevec;
127   char **ktypevec;
128   char **btypevec;
129   int numk;
130   int numb;
131   int ksize;
132   int bsize;
133   int ntypes;
134   int typevec_size;
135   int constructor;
136   int destructor;
137   int static_type;	/* A static member function */
138   int temp_start;       /* index in demangled to start of template args */
139   int type_quals;       /* The type qualifiers.  */
140   int dllimported;	/* Symbol imported from a PE DLL */
141   char **tmpl_argvec;   /* Template function arguments. */
142   int ntmpl_args;       /* The number of template function arguments. */
143   int forgetting_types; /* Nonzero if we are not remembering the types
144 			   we see.  */
145   string* previous_argument; /* The last function argument demangled.  */
146   int nrepeats;         /* The number of times to repeat the previous
147 			   argument.  */
148 };
149 
150 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
151 #define PRINT_ARG_TYPES       (work -> options & DMGL_PARAMS)
152 
153 static const struct optable
154 {
155   const char *const in;
156   const char *const out;
157   const int flags;
158 } optable[] = {
159   {"nw",	  " new",	DMGL_ANSI},	/* new (1.92,	 ansi) */
160   {"dl",	  " delete",	DMGL_ANSI},	/* new (1.92,	 ansi) */
161   {"new",	  " new",	0},		/* old (1.91,	 and 1.x) */
162   {"delete",	  " delete",	0},		/* old (1.91,	 and 1.x) */
163   {"vn",	  " new []",	DMGL_ANSI},	/* GNU, pending ansi */
164   {"vd",	  " delete []",	DMGL_ANSI},	/* GNU, pending ansi */
165   {"as",	  "=",		DMGL_ANSI},	/* ansi */
166   {"ne",	  "!=",		DMGL_ANSI},	/* old, ansi */
167   {"eq",	  "==",		DMGL_ANSI},	/* old,	ansi */
168   {"ge",	  ">=",		DMGL_ANSI},	/* old,	ansi */
169   {"gt",	  ">",		DMGL_ANSI},	/* old,	ansi */
170   {"le",	  "<=",		DMGL_ANSI},	/* old,	ansi */
171   {"lt",	  "<",		DMGL_ANSI},	/* old,	ansi */
172   {"plus",	  "+",		0},		/* old */
173   {"pl",	  "+",		DMGL_ANSI},	/* ansi */
174   {"apl",	  "+=",		DMGL_ANSI},	/* ansi */
175   {"minus",	  "-",		0},		/* old */
176   {"mi",	  "-",		DMGL_ANSI},	/* ansi */
177   {"ami",	  "-=",		DMGL_ANSI},	/* ansi */
178   {"mult",	  "*",		0},		/* old */
179   {"ml",	  "*",		DMGL_ANSI},	/* ansi */
180   {"amu",	  "*=",		DMGL_ANSI},	/* ansi (ARM/Lucid) */
181   {"aml",	  "*=",		DMGL_ANSI},	/* ansi (GNU/g++) */
182   {"convert",	  "+",		0},		/* old (unary +) */
183   {"negate",	  "-",		0},		/* old (unary -) */
184   {"trunc_mod",	  "%",		0},		/* old */
185   {"md",	  "%",		DMGL_ANSI},	/* ansi */
186   {"amd",	  "%=",		DMGL_ANSI},	/* ansi */
187   {"trunc_div",	  "/",		0},		/* old */
188   {"dv",	  "/",		DMGL_ANSI},	/* ansi */
189   {"adv",	  "/=",		DMGL_ANSI},	/* ansi */
190   {"truth_andif", "&&",		0},		/* old */
191   {"aa",	  "&&",		DMGL_ANSI},	/* ansi */
192   {"truth_orif",  "||",		0},		/* old */
193   {"oo",	  "||",		DMGL_ANSI},	/* ansi */
194   {"truth_not",	  "!",		0},		/* old */
195   {"nt",	  "!",		DMGL_ANSI},	/* ansi */
196   {"postincrement","++",	0},		/* old */
197   {"pp",	  "++",		DMGL_ANSI},	/* ansi */
198   {"postdecrement","--",	0},		/* old */
199   {"mm",	  "--",		DMGL_ANSI},	/* ansi */
200   {"bit_ior",	  "|",		0},		/* old */
201   {"or",	  "|",		DMGL_ANSI},	/* ansi */
202   {"aor",	  "|=",		DMGL_ANSI},	/* ansi */
203   {"bit_xor",	  "^",		0},		/* old */
204   {"er",	  "^",		DMGL_ANSI},	/* ansi */
205   {"aer",	  "^=",		DMGL_ANSI},	/* ansi */
206   {"bit_and",	  "&",		0},		/* old */
207   {"ad",	  "&",		DMGL_ANSI},	/* ansi */
208   {"aad",	  "&=",		DMGL_ANSI},	/* ansi */
209   {"bit_not",	  "~",		0},		/* old */
210   {"co",	  "~",		DMGL_ANSI},	/* ansi */
211   {"call",	  "()",		0},		/* old */
212   {"cl",	  "()",		DMGL_ANSI},	/* ansi */
213   {"alshift",	  "<<",		0},		/* old */
214   {"ls",	  "<<",		DMGL_ANSI},	/* ansi */
215   {"als",	  "<<=",	DMGL_ANSI},	/* ansi */
216   {"arshift",	  ">>",		0},		/* old */
217   {"rs",	  ">>",		DMGL_ANSI},	/* ansi */
218   {"ars",	  ">>=",	DMGL_ANSI},	/* ansi */
219   {"component",	  "->",		0},		/* old */
220   {"pt",	  "->",		DMGL_ANSI},	/* ansi; Lucid C++ form */
221   {"rf",	  "->",		DMGL_ANSI},	/* ansi; ARM/GNU form */
222   {"indirect",	  "*",		0},		/* old */
223   {"method_call",  "->()",	0},		/* old */
224   {"addr",	  "&",		0},		/* old (unary &) */
225   {"array",	  "[]",		0},		/* old */
226   {"vc",	  "[]",		DMGL_ANSI},	/* ansi */
227   {"compound",	  ", ",		0},		/* old */
228   {"cm",	  ", ",		DMGL_ANSI},	/* ansi */
229   {"cond",	  "?:",		0},		/* old */
230   {"cn",	  "?:",		DMGL_ANSI},	/* pseudo-ansi */
231   {"max",	  ">?",		0},		/* old */
232   {"mx",	  ">?",		DMGL_ANSI},	/* pseudo-ansi */
233   {"min",	  "<?",		0},		/* old */
234   {"mn",	  "<?",		DMGL_ANSI},	/* pseudo-ansi */
235   {"nop",	  "",		0},		/* old (for operator=) */
236   {"rm",	  "->*",	DMGL_ANSI},	/* ansi */
237   {"sz",          "sizeof ",    DMGL_ANSI}      /* pseudo-ansi */
238 };
239 
240 /* These values are used to indicate the various type varieties.
241    They are all non-zero so that they can be used as `success'
242    values.  */
243 typedef enum type_kind_t
244 {
245   tk_none,
246   tk_pointer,
247   tk_reference,
248   tk_integral,
249   tk_bool,
250   tk_char,
251   tk_real
252 } type_kind_t;
253 
254 const struct demangler_engine libiberty_demanglers[] =
255 {
256   {
257     NO_DEMANGLING_STYLE_STRING,
258     no_demangling,
259     "Demangling disabled"
260   }
261   ,
262   {
263     AUTO_DEMANGLING_STYLE_STRING,
264       auto_demangling,
265       "Automatic selection based on executable"
266   }
267   ,
268   {
269     GNU_DEMANGLING_STYLE_STRING,
270       gnu_demangling,
271       "GNU (g++) style demangling"
272   }
273   ,
274   {
275     LUCID_DEMANGLING_STYLE_STRING,
276       lucid_demangling,
277       "Lucid (lcc) style demangling"
278   }
279   ,
280   {
281     ARM_DEMANGLING_STYLE_STRING,
282       arm_demangling,
283       "ARM style demangling"
284   }
285   ,
286   {
287     HP_DEMANGLING_STYLE_STRING,
288       hp_demangling,
289       "HP (aCC) style demangling"
290   }
291   ,
292   {
293     EDG_DEMANGLING_STYLE_STRING,
294       edg_demangling,
295       "EDG style demangling"
296   }
297   ,
298   {
299     GNU_V3_DEMANGLING_STYLE_STRING,
300     gnu_v3_demangling,
301     "GNU (g++) V3 ABI-style demangling"
302   }
303   ,
304   {
305     JAVA_DEMANGLING_STYLE_STRING,
306     java_demangling,
307     "Java style demangling"
308   }
309   ,
310   {
311     GNAT_DEMANGLING_STYLE_STRING,
312     gnat_demangling,
313     "GNAT style demangling"
314   }
315   ,
316   {
317     NULL, unknown_demangling, NULL
318   }
319 };
320 
321 #define STRING_EMPTY(str)	((str) -> b == (str) -> p)
322 #define APPEND_BLANK(str)	{if (!STRING_EMPTY(str)) \
323     string_append(str, " ");}
324 #define LEN_STRING(str)         ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
325 
326 /* The scope separator appropriate for the language being demangled.  */
327 
328 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
329 
330 #define ARM_VTABLE_STRING "__vtbl__"	/* Lucid/ARM virtual table prefix */
331 #define ARM_VTABLE_STRLEN 8		/* strlen (ARM_VTABLE_STRING) */
332 
333 /* Prototypes for local functions */
334 
335 static void delete_work_stuff (struct work_stuff *);
336 
337 static void delete_non_B_K_work_stuff (struct work_stuff *);
338 
339 static char *mop_up (struct work_stuff *, string *, int);
340 
341 static void squangle_mop_up (struct work_stuff *);
342 
343 static void work_stuff_copy_to_from (struct work_stuff *, struct work_stuff *);
344 
345 #if 0
346 static int
347 demangle_method_args (struct work_stuff *, const char **, string *);
348 #endif
349 
350 static char *
351 internal_cplus_demangle (struct work_stuff *, const char *);
352 
353 static int
354 demangle_template_template_parm (struct work_stuff *work,
355                                  const char **, string *);
356 
357 static int
358 demangle_template (struct work_stuff *work, const char **, string *,
359                    string *, int, int);
360 
361 static int
362 arm_pt (struct work_stuff *, const char *, int, const char **,
363         const char **);
364 
365 static int
366 demangle_class_name (struct work_stuff *, const char **, string *);
367 
368 static int
369 demangle_qualified (struct work_stuff *, const char **, string *,
370                     int, int);
371 
372 static int demangle_class (struct work_stuff *, const char **, string *);
373 
374 static int demangle_fund_type (struct work_stuff *, const char **, string *);
375 
376 static int demangle_signature (struct work_stuff *, const char **, string *);
377 
378 static int demangle_prefix (struct work_stuff *, const char **, string *);
379 
380 static int gnu_special (struct work_stuff *, const char **, string *);
381 
382 static int arm_special (const char **, string *);
383 
384 static void string_need (string *, int);
385 
386 static void string_delete (string *);
387 
388 static void
389 string_init (string *);
390 
391 static void string_clear (string *);
392 
393 #if 0
394 static int string_empty (string *);
395 #endif
396 
397 static void string_append (string *, const char *);
398 
399 static void string_appends (string *, string *);
400 
401 static void string_appendn (string *, const char *, int);
402 
403 static void string_prepend (string *, const char *);
404 
405 static void string_prependn (string *, const char *, int);
406 
407 static void string_append_template_idx (string *, int);
408 
409 static int get_count (const char **, int *);
410 
411 static int consume_count (const char **);
412 
413 static int consume_count_with_underscores (const char**);
414 
415 static int demangle_args (struct work_stuff *, const char **, string *);
416 
417 static int demangle_nested_args (struct work_stuff*, const char**, string*);
418 
419 static int do_type (struct work_stuff *, const char **, string *);
420 
421 static int do_arg (struct work_stuff *, const char **, string *);
422 
423 static void
424 demangle_function_name (struct work_stuff *, const char **, string *,
425                         const char *);
426 
427 static int
428 iterate_demangle_function (struct work_stuff *,
429                            const char **, string *, const char *);
430 
431 static void remember_type (struct work_stuff *, const char *, int);
432 
433 static void remember_Btype (struct work_stuff *, const char *, int, int);
434 
435 static int register_Btype (struct work_stuff *);
436 
437 static void remember_Ktype (struct work_stuff *, const char *, int);
438 
439 static void forget_types (struct work_stuff *);
440 
441 static void forget_B_and_K_types (struct work_stuff *);
442 
443 static void string_prepends (string *, string *);
444 
445 static int
446 demangle_template_value_parm (struct work_stuff*, const char**,
447                               string*, type_kind_t);
448 
449 static int
450 do_hpacc_template_const_value (struct work_stuff *, const char **, string *);
451 
452 static int
453 do_hpacc_template_literal (struct work_stuff *, const char **, string *);
454 
455 static int snarf_numeric_literal (const char **, string *);
456 
457 /* There is a TYPE_QUAL value for each type qualifier.  They can be
458    combined by bitwise-or to form the complete set of qualifiers for a
459    type.  */
460 
461 #define TYPE_UNQUALIFIED   0x0
462 #define TYPE_QUAL_CONST    0x1
463 #define TYPE_QUAL_VOLATILE 0x2
464 #define TYPE_QUAL_RESTRICT 0x4
465 
466 static int code_for_qualifier (int);
467 
468 static const char* qualifier_string (int);
469 
470 static const char* demangle_qualifier (int);
471 
472 static int demangle_expression (struct work_stuff *, const char **, string *,
473                                 type_kind_t);
474 
475 static int
476 demangle_integral_value (struct work_stuff *, const char **, string *);
477 
478 static int
479 demangle_real_value (struct work_stuff *, const char **, string *);
480 
481 static void
482 demangle_arm_hp_template (struct work_stuff *, const char **, int, string *);
483 
484 static void
485 recursively_demangle (struct work_stuff *, const char **, string *, int);
486 
487 static void grow_vect (char **, size_t *, size_t, int);
488 
489 /* Translate count to integer, consuming tokens in the process.
490    Conversion terminates on the first non-digit character.
491 
492    Trying to consume something that isn't a count results in no
493    consumption of input and a return of -1.
494 
495    Overflow consumes the rest of the digits, and returns -1.  */
496 
497 static int
consume_count(const char ** type)498 consume_count (const char **type)
499 {
500   int count = 0;
501 
502   if (! ISDIGIT ((unsigned char)**type))
503     return -1;
504 
505   while (ISDIGIT ((unsigned char)**type))
506     {
507       count *= 10;
508 
509       /* Check for overflow.
510 	 We assume that count is represented using two's-complement;
511 	 no power of two is divisible by ten, so if an overflow occurs
512 	 when multiplying by ten, the result will not be a multiple of
513 	 ten.  */
514       if ((count % 10) != 0)
515 	{
516 	  while (ISDIGIT ((unsigned char) **type))
517 	    (*type)++;
518 	  return -1;
519 	}
520 
521       count += **type - '0';
522       (*type)++;
523     }
524 
525   if (count < 0)
526     count = -1;
527 
528   return (count);
529 }
530 
531 
532 /* Like consume_count, but for counts that are preceded and followed
533    by '_' if they are greater than 10.  Also, -1 is returned for
534    failure, since 0 can be a valid value.  */
535 
536 static int
consume_count_with_underscores(const char ** mangled)537 consume_count_with_underscores (const char **mangled)
538 {
539   int idx;
540 
541   if (**mangled == '_')
542     {
543       (*mangled)++;
544       if (!ISDIGIT ((unsigned char)**mangled))
545 	return -1;
546 
547       idx = consume_count (mangled);
548       if (**mangled != '_')
549 	/* The trailing underscore was missing. */
550 	return -1;
551 
552       (*mangled)++;
553     }
554   else
555     {
556       if (**mangled < '0' || **mangled > '9')
557 	return -1;
558 
559       idx = **mangled - '0';
560       (*mangled)++;
561     }
562 
563   return idx;
564 }
565 
566 /* C is the code for a type-qualifier.  Return the TYPE_QUAL
567    corresponding to this qualifier.  */
568 
569 static int
code_for_qualifier(int c)570 code_for_qualifier (int c)
571 {
572   switch (c)
573     {
574     case 'C':
575       return TYPE_QUAL_CONST;
576 
577     case 'V':
578       return TYPE_QUAL_VOLATILE;
579 
580     case 'u':
581       return TYPE_QUAL_RESTRICT;
582 
583     default:
584       break;
585     }
586 
587   /* C was an invalid qualifier.  */
588   abort ();
589 }
590 
591 /* Return the string corresponding to the qualifiers given by
592    TYPE_QUALS.  */
593 
594 static const char*
qualifier_string(int type_quals)595 qualifier_string (int type_quals)
596 {
597   switch (type_quals)
598     {
599     case TYPE_UNQUALIFIED:
600       return "";
601 
602     case TYPE_QUAL_CONST:
603       return "const";
604 
605     case TYPE_QUAL_VOLATILE:
606       return "volatile";
607 
608     case TYPE_QUAL_RESTRICT:
609       return "__restrict";
610 
611     case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
612       return "const volatile";
613 
614     case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
615       return "const __restrict";
616 
617     case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
618       return "volatile __restrict";
619 
620     case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
621       return "const volatile __restrict";
622 
623     default:
624       break;
625     }
626 
627   /* TYPE_QUALS was an invalid qualifier set.  */
628   abort ();
629 }
630 
631 /* C is the code for a type-qualifier.  Return the string
632    corresponding to this qualifier.  This function should only be
633    called with a valid qualifier code.  */
634 
635 static const char*
demangle_qualifier(int c)636 demangle_qualifier (int c)
637 {
638   return qualifier_string (code_for_qualifier (c));
639 }
640 
641 int
cplus_demangle_opname(const char * opname,char * result,int options,size_t ressiz)642 cplus_demangle_opname (const char *opname, char *result, int options,
643                        size_t ressiz)
644 {
645   int len, len1, ret;
646   string type;
647   struct work_stuff work[1];
648   const char *tem;
649 
650   len = strlen(opname);
651   result[0] = '\0';
652   ret = 0;
653   memset ((char *) work, 0, sizeof (work));
654   work->options = options;
655 
656   if (opname[0] == '_' && opname[1] == '_'
657       && opname[2] == 'o' && opname[3] == 'p')
658     {
659       /* ANSI.  */
660       /* type conversion operator.  */
661       tem = opname + 4;
662       if (do_type (work, &tem, &type))
663 	{
664 	  strlcat (result, "operator ", ressiz);
665 	  strncat (result, type.b, type.p - type.b);
666 	  string_delete (&type);
667 	  ret = 1;
668 	}
669     }
670   else if (opname[0] == '_' && opname[1] == '_'
671 	   && ISLOWER((unsigned char)opname[2])
672 	   && ISLOWER((unsigned char)opname[3]))
673     {
674       if (opname[4] == '\0')
675 	{
676 	  /* Operator.  */
677 	  size_t i;
678 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
679 	    {
680 	      if (strlen (optable[i].in) == 2
681 		  && memcmp (optable[i].in, opname + 2, 2) == 0)
682 		{
683 		  strlcat (result, "operator", ressiz);
684 		  strlcat (result, optable[i].out, ressiz);
685 		  ret = 1;
686 		  break;
687 		}
688 	    }
689 	}
690       else
691 	{
692 	  if (opname[2] == 'a' && opname[5] == '\0')
693 	    {
694 	      /* Assignment.  */
695 	      size_t i;
696 	      for (i = 0; i < ARRAY_SIZE (optable); i++)
697 		{
698 		  if (strlen (optable[i].in) == 3
699 		      && memcmp (optable[i].in, opname + 2, 3) == 0)
700 		    {
701 		      strlcat (result, "operator", ressiz);
702 		      strlcat (result, optable[i].out, ressiz);
703 		      ret = 1;
704 		      break;
705 		    }
706 		}
707 	    }
708 	}
709     }
710   else if (len >= 3
711 	   && opname[0] == 'o'
712 	   && opname[1] == 'p'
713 	   && strchr (cplus_markers, opname[2]) != NULL)
714     {
715       /* see if it's an assignment expression */
716       if (len >= 10 /* op$assign_ */
717 	  && memcmp (opname + 3, "assign_", 7) == 0)
718 	{
719 	  size_t i;
720 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
721 	    {
722 	      len1 = len - 10;
723 	      if ((int) strlen (optable[i].in) == len1
724 		  && memcmp (optable[i].in, opname + 10, len1) == 0)
725 		{
726 		  strlcat (result, "operator", ressiz);
727 		  strlcat (result, optable[i].out, ressiz);
728 		  strlcat (result, "=", ressiz);
729 		  ret = 1;
730 		  break;
731 		}
732 	    }
733 	}
734       else
735 	{
736 	  size_t i;
737 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
738 	    {
739 	      len1 = len - 3;
740 	      if ((int) strlen (optable[i].in) == len1
741 		  && memcmp (optable[i].in, opname + 3, len1) == 0)
742 		{
743 		  strlcat (result, "operator", ressiz);
744 		  strlcat (result, optable[i].out, ressiz);
745 		  ret = 1;
746 		  break;
747 		}
748 	    }
749 	}
750     }
751   else if (len >= 5 && memcmp (opname, "type", 4) == 0
752 	   && strchr (cplus_markers, opname[4]) != NULL)
753     {
754       /* type conversion operator */
755       tem = opname + 5;
756       if (do_type (work, &tem, &type))
757 	{
758 	  strlcat (result, "operator ", ressiz);
759 	  strncat (result, type.b, type.p - type.b);
760 	  string_delete (&type);
761 	  ret = 1;
762 	}
763     }
764   squangle_mop_up (work);
765   return ret;
766 
767 }
768 
769 /* Takes operator name as e.g. "++" and returns mangled
770    operator name (e.g. "postincrement_expr"), or NULL if not found.
771 
772    If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
773    if OPTIONS & DMGL_ANSI == 0, return the old GNU name.  */
774 
775 const char *
cplus_mangle_opname(const char * opname,int options)776 cplus_mangle_opname (const char *opname, int options)
777 {
778   size_t i;
779   int len;
780 
781   len = strlen (opname);
782   for (i = 0; i < ARRAY_SIZE (optable); i++)
783     {
784       if ((int) strlen (optable[i].out) == len
785 	  && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
786 	  && memcmp (optable[i].out, opname, len) == 0)
787 	return optable[i].in;
788     }
789   return (0);
790 }
791 
792 /* Add a routine to set the demangling style to be sure it is valid and
793    allow for any demangler initialization that maybe necessary. */
794 
795 enum demangling_styles
cplus_demangle_set_style(enum demangling_styles style)796 cplus_demangle_set_style (enum demangling_styles style)
797 {
798   const struct demangler_engine *demangler = libiberty_demanglers;
799 
800   for (; demangler->demangling_style != unknown_demangling; ++demangler)
801     if (style == demangler->demangling_style)
802       {
803 	current_demangling_style = style;
804 	return current_demangling_style;
805       }
806 
807   return unknown_demangling;
808 }
809 
810 /* Do string name to style translation */
811 
812 enum demangling_styles
cplus_demangle_name_to_style(const char * name)813 cplus_demangle_name_to_style (const char *name)
814 {
815   const struct demangler_engine *demangler = libiberty_demanglers;
816 
817   for (; demangler->demangling_style != unknown_demangling; ++demangler)
818     if (strcmp (name, demangler->demangling_style_name) == 0)
819       return demangler->demangling_style;
820 
821   return unknown_demangling;
822 }
823 
824 /* char *cplus_demangle (const char *mangled, int options)
825 
826    If MANGLED is a mangled function name produced by GNU C++, then
827    a pointer to a @code{malloc}ed string giving a C++ representation
828    of the name will be returned; otherwise NULL will be returned.
829    It is the caller's responsibility to free the string which
830    is returned.
831 
832    The OPTIONS arg may contain one or more of the following bits:
833 
834    	DMGL_ANSI	ANSI qualifiers such as `const' and `void' are
835 			included.
836 	DMGL_PARAMS	Function parameters are included.
837 
838    For example,
839 
840    cplus_demangle ("foo__1Ai", DMGL_PARAMS)		=> "A::foo(int)"
841    cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI)	=> "A::foo(int)"
842    cplus_demangle ("foo__1Ai", 0)			=> "A::foo"
843 
844    cplus_demangle ("foo__1Afe", DMGL_PARAMS)		=> "A::foo(float,...)"
845    cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
846    cplus_demangle ("foo__1Afe", 0)			=> "A::foo"
847 
848    Note that any leading underscores, or other such characters prepended by
849    the compilation system, are presumed to have already been stripped from
850    MANGLED.  */
851 
852 char *
cplus_demangle(const char * mangled,int options)853 cplus_demangle (const char *mangled, int options)
854 {
855   char *ret;
856   struct work_stuff work[1];
857 
858   if (current_demangling_style == no_demangling)
859     return xstrdup (mangled);
860 
861   memset ((char *) work, 0, sizeof (work));
862   work->options = options;
863   if ((work->options & DMGL_STYLE_MASK) == 0)
864     work->options |= (int) current_demangling_style & DMGL_STYLE_MASK;
865 
866   /* The V3 ABI demangling is implemented elsewhere.  */
867   if (GNU_V3_DEMANGLING || AUTO_DEMANGLING)
868     {
869       ret = cplus_demangle_v3 (mangled, work->options);
870       if (ret || GNU_V3_DEMANGLING)
871 	return ret;
872     }
873 
874   if (JAVA_DEMANGLING)
875     {
876       ret = java_demangle_v3 (mangled);
877       if (ret)
878         return ret;
879     }
880 
881   if (GNAT_DEMANGLING)
882     return ada_demangle(mangled,options);
883 
884   ret = internal_cplus_demangle (work, mangled);
885   squangle_mop_up (work);
886   return (ret);
887 }
888 
889 
890 /* Assuming *OLD_VECT points to an array of *SIZE objects of size
891    ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects,
892    updating *OLD_VECT and *SIZE as necessary.  */
893 
894 static void
grow_vect(char ** old_vect,size_t * size,size_t min_size,int element_size)895 grow_vect (char **old_vect, size_t *size, size_t min_size, int element_size)
896 {
897   if (*size < min_size)
898     {
899       *size *= 2;
900       if (*size < min_size)
901 	*size = min_size;
902       *old_vect = XRESIZEVAR (char, *old_vect, *size * element_size);
903     }
904 }
905 
906 /* Demangle ada names:
907    1. Discard final __{DIGIT}+ or ${DIGIT}+
908    2. Convert other instances of embedded "__" to `.'.
909    3. Discard leading _ada_.
910    4. Remove everything after first ___ if it is followed by 'X'.
911    5. Put symbols that should be suppressed in <...> brackets.
912    The resulting string is valid until the next call of ada_demangle.  */
913 
914 static char *
ada_demangle(const char * mangled,int option ATTRIBUTE_UNUSED)915 ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
916 {
917   int i, j;
918   int len0;
919   const char* p;
920   char *demangled = NULL;
921   int changed;
922   size_t demangled_size = 0;
923 
924   changed = 0;
925 
926   if (strncmp (mangled, "_ada_", 5) == 0)
927     {
928       mangled += 5;
929       changed = 1;
930     }
931 
932   if (mangled[0] == '_' || mangled[0] == '<')
933     goto Suppress;
934 
935   p = strstr (mangled, "___");
936   if (p == NULL)
937     len0 = strlen (mangled);
938   else
939     {
940       if (p[3] == 'X')
941 	{
942 	  len0 = p - mangled;
943 	  changed = 1;
944 	}
945       else
946 	goto Suppress;
947     }
948 
949   /* Make demangled big enough for possible expansion by operator name.  */
950   grow_vect (&demangled,
951 	     &demangled_size,  2 * len0 + 1,
952 	     sizeof (char));
953 
954   if (ISDIGIT ((unsigned char) mangled[len0 - 1])) {
955     for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1)
956       ;
957     if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_')
958       {
959 	len0 = i - 1;
960 	changed = 1;
961       }
962     else if (mangled[i] == '$')
963       {
964 	len0 = i;
965 	changed = 1;
966       }
967   }
968 
969   for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]);
970        i += 1, j += 1)
971     demangled[j] = mangled[i];
972 
973   while (i < len0)
974     {
975       if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_')
976 	{
977 	  demangled[j] = '.';
978 	  changed = 1;
979 	  i += 2; j += 1;
980 	}
981       else
982 	{
983 	  demangled[j] = mangled[i];
984 	  i += 1;  j += 1;
985 	}
986     }
987   demangled[j] = '\000';
988 
989   for (i = 0; demangled[i] != '\0'; i += 1)
990     if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ')
991       goto Suppress;
992 
993   if (! changed)
994     return NULL;
995   else
996     return demangled;
997 
998  Suppress:
999   grow_vect (&demangled,
1000 	     &demangled_size,  strlen (mangled) + 3,
1001 	     sizeof (char));
1002 
1003   if (mangled[0] == '<')
1004      strlcpy (demangled, mangled, demangled_size);
1005   else
1006     snprintf (demangled, demangled_size, "<%s>", mangled);
1007 
1008   return demangled;
1009 }
1010 
1011 /* This function performs most of what cplus_demangle use to do, but
1012    to be able to demangle a name with a B, K or n code, we need to
1013    have a longer term memory of what types have been seen. The original
1014    now initializes and cleans up the squangle code info, while internal
1015    calls go directly to this routine to avoid resetting that info. */
1016 
1017 static char *
internal_cplus_demangle(struct work_stuff * work,const char * mangled)1018 internal_cplus_demangle (struct work_stuff *work, const char *mangled)
1019 {
1020 
1021   string decl;
1022   int success = 0;
1023   char *demangled = NULL;
1024   int s1, s2, s3, s4;
1025   s1 = work->constructor;
1026   s2 = work->destructor;
1027   s3 = work->static_type;
1028   s4 = work->type_quals;
1029   work->constructor = work->destructor = 0;
1030   work->type_quals = TYPE_UNQUALIFIED;
1031   work->dllimported = 0;
1032 
1033   if ((mangled != NULL) && (*mangled != '\0'))
1034     {
1035       string_init (&decl);
1036 
1037       /* First check to see if gnu style demangling is active and if the
1038 	 string to be demangled contains a CPLUS_MARKER.  If so, attempt to
1039 	 recognize one of the gnu special forms rather than looking for a
1040 	 standard prefix.  In particular, don't worry about whether there
1041 	 is a "__" string in the mangled string.  Consider "_$_5__foo" for
1042 	 example.  */
1043 
1044       if ((AUTO_DEMANGLING || GNU_DEMANGLING))
1045 	{
1046 	  success = gnu_special (work, &mangled, &decl);
1047 	}
1048       if (!success)
1049 	{
1050 	  success = demangle_prefix (work, &mangled, &decl);
1051 	}
1052       if (success && (*mangled != '\0'))
1053 	{
1054 	  success = demangle_signature (work, &mangled, &decl);
1055 	}
1056       if (work->constructor == 2)
1057         {
1058           string_prepend (&decl, "global constructors keyed to ");
1059           work->constructor = 0;
1060         }
1061       else if (work->destructor == 2)
1062         {
1063           string_prepend (&decl, "global destructors keyed to ");
1064           work->destructor = 0;
1065         }
1066       else if (work->dllimported == 1)
1067         {
1068           string_prepend (&decl, "import stub for ");
1069           work->dllimported = 0;
1070         }
1071       demangled = mop_up (work, &decl, success);
1072     }
1073   work->constructor = s1;
1074   work->destructor = s2;
1075   work->static_type = s3;
1076   work->type_quals = s4;
1077   return demangled;
1078 }
1079 
1080 
1081 /* Clear out and squangling related storage */
1082 static void
squangle_mop_up(struct work_stuff * work)1083 squangle_mop_up (struct work_stuff *work)
1084 {
1085   /* clean up the B and K type mangling types. */
1086   forget_B_and_K_types (work);
1087   if (work -> btypevec != NULL)
1088     {
1089       free ((char *) work -> btypevec);
1090     }
1091   if (work -> ktypevec != NULL)
1092     {
1093       free ((char *) work -> ktypevec);
1094     }
1095 }
1096 
1097 
1098 /* Copy the work state and storage.  */
1099 
1100 static void
work_stuff_copy_to_from(struct work_stuff * to,struct work_stuff * from)1101 work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from)
1102 {
1103   int i;
1104 
1105   delete_work_stuff (to);
1106 
1107   /* Shallow-copy scalars.  */
1108   memcpy (to, from, sizeof (*to));
1109 
1110   /* Deep-copy dynamic storage.  */
1111   if (from->typevec_size)
1112     to->typevec = XNEWVEC (char *, from->typevec_size);
1113 
1114   for (i = 0; i < from->ntypes; i++)
1115     {
1116       int len = strlen (from->typevec[i]) + 1;
1117 
1118       to->typevec[i] = XNEWVEC (char, len);
1119       memcpy (to->typevec[i], from->typevec[i], len);
1120     }
1121 
1122   if (from->ksize)
1123     to->ktypevec = XNEWVEC (char *, from->ksize);
1124 
1125   for (i = 0; i < from->numk; i++)
1126     {
1127       int len = strlen (from->ktypevec[i]) + 1;
1128 
1129       to->ktypevec[i] = XNEWVEC (char, len);
1130       memcpy (to->ktypevec[i], from->ktypevec[i], len);
1131     }
1132 
1133   if (from->bsize)
1134     to->btypevec = XNEWVEC (char *, from->bsize);
1135 
1136   for (i = 0; i < from->numb; i++)
1137     {
1138       int len = strlen (from->btypevec[i]) + 1;
1139 
1140       to->btypevec[i] = XNEWVEC (char , len);
1141       memcpy (to->btypevec[i], from->btypevec[i], len);
1142     }
1143 
1144   if (from->ntmpl_args)
1145     to->tmpl_argvec = XNEWVEC (char *, from->ntmpl_args);
1146 
1147   for (i = 0; i < from->ntmpl_args; i++)
1148     {
1149       int len = strlen (from->tmpl_argvec[i]) + 1;
1150 
1151       to->tmpl_argvec[i] = XNEWVEC (char, len);
1152       memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len);
1153     }
1154 
1155   if (from->previous_argument)
1156     {
1157       to->previous_argument = XNEW (string);
1158       string_init (to->previous_argument);
1159       string_appends (to->previous_argument, from->previous_argument);
1160     }
1161 }
1162 
1163 
1164 /* Delete dynamic stuff in work_stuff that is not to be re-used.  */
1165 
1166 static void
delete_non_B_K_work_stuff(struct work_stuff * work)1167 delete_non_B_K_work_stuff (struct work_stuff *work)
1168 {
1169   /* Discard the remembered types, if any.  */
1170 
1171   forget_types (work);
1172   if (work -> typevec != NULL)
1173     {
1174       free ((char *) work -> typevec);
1175       work -> typevec = NULL;
1176       work -> typevec_size = 0;
1177     }
1178   if (work->tmpl_argvec)
1179     {
1180       int i;
1181 
1182       for (i = 0; i < work->ntmpl_args; i++)
1183 	if (work->tmpl_argvec[i])
1184 	  free ((char*) work->tmpl_argvec[i]);
1185 
1186       free ((char*) work->tmpl_argvec);
1187       work->tmpl_argvec = NULL;
1188     }
1189   if (work->previous_argument)
1190     {
1191       string_delete (work->previous_argument);
1192       free ((char*) work->previous_argument);
1193       work->previous_argument = NULL;
1194     }
1195 }
1196 
1197 
1198 /* Delete all dynamic storage in work_stuff.  */
1199 static void
delete_work_stuff(struct work_stuff * work)1200 delete_work_stuff (struct work_stuff *work)
1201 {
1202   delete_non_B_K_work_stuff (work);
1203   squangle_mop_up (work);
1204 }
1205 
1206 
1207 /* Clear out any mangled storage */
1208 
1209 static char *
mop_up(struct work_stuff * work,string * declp,int success)1210 mop_up (struct work_stuff *work, string *declp, int success)
1211 {
1212   char *demangled = NULL;
1213 
1214   delete_non_B_K_work_stuff (work);
1215 
1216   /* If demangling was successful, ensure that the demangled string is null
1217      terminated and return it.  Otherwise, free the demangling decl.  */
1218 
1219   if (!success)
1220     {
1221       string_delete (declp);
1222     }
1223   else
1224     {
1225       string_appendn (declp, "", 1);
1226       demangled = declp->b;
1227     }
1228   return (demangled);
1229 }
1230 
1231 /*
1232 
1233 LOCAL FUNCTION
1234 
1235 	demangle_signature -- demangle the signature part of a mangled name
1236 
1237 SYNOPSIS
1238 
1239 	static int
1240 	demangle_signature (struct work_stuff *work, const char **mangled,
1241 			    string *declp);
1242 
1243 DESCRIPTION
1244 
1245 	Consume and demangle the signature portion of the mangled name.
1246 
1247 	DECLP is the string where demangled output is being built.  At
1248 	entry it contains the demangled root name from the mangled name
1249 	prefix.  I.E. either a demangled operator name or the root function
1250 	name.  In some special cases, it may contain nothing.
1251 
1252 	*MANGLED points to the current unconsumed location in the mangled
1253 	name.  As tokens are consumed and demangling is performed, the
1254 	pointer is updated to continuously point at the next token to
1255 	be consumed.
1256 
1257 	Demangling GNU style mangled names is nasty because there is no
1258 	explicit token that marks the start of the outermost function
1259 	argument list.  */
1260 
1261 static int
demangle_signature(struct work_stuff * work,const char ** mangled,string * declp)1262 demangle_signature (struct work_stuff *work,
1263                     const char **mangled, string *declp)
1264 {
1265   int success = 1;
1266   int func_done = 0;
1267   int expect_func = 0;
1268   int expect_return_type = 0;
1269   const char *oldmangled = NULL;
1270   string trawname;
1271   string tname;
1272 
1273   while (success && (**mangled != '\0'))
1274     {
1275       switch (**mangled)
1276 	{
1277 	case 'Q':
1278 	  oldmangled = *mangled;
1279 	  success = demangle_qualified (work, mangled, declp, 1, 0);
1280 	  if (success)
1281 	    remember_type (work, oldmangled, *mangled - oldmangled);
1282 	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
1283 	    expect_func = 1;
1284 	  oldmangled = NULL;
1285 	  break;
1286 
1287         case 'K':
1288 	  oldmangled = *mangled;
1289 	  success = demangle_qualified (work, mangled, declp, 1, 0);
1290 	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
1291 	    {
1292 	      expect_func = 1;
1293 	    }
1294 	  oldmangled = NULL;
1295 	  break;
1296 
1297 	case 'S':
1298 	  /* Static member function */
1299 	  if (oldmangled == NULL)
1300 	    {
1301 	      oldmangled = *mangled;
1302 	    }
1303 	  (*mangled)++;
1304 	  work -> static_type = 1;
1305 	  break;
1306 
1307 	case 'C':
1308 	case 'V':
1309 	case 'u':
1310 	  work->type_quals |= code_for_qualifier (**mangled);
1311 
1312 	  /* a qualified member function */
1313 	  if (oldmangled == NULL)
1314 	    oldmangled = *mangled;
1315 	  (*mangled)++;
1316 	  break;
1317 
1318 	case 'L':
1319 	  /* Local class name follows after "Lnnn_" */
1320 	  if (HP_DEMANGLING)
1321 	    {
1322 	      while (**mangled && (**mangled != '_'))
1323 		(*mangled)++;
1324 	      if (!**mangled)
1325 		success = 0;
1326 	      else
1327 		(*mangled)++;
1328 	    }
1329 	  else
1330 	    success = 0;
1331 	  break;
1332 
1333 	case '0': case '1': case '2': case '3': case '4':
1334 	case '5': case '6': case '7': case '8': case '9':
1335 	  if (oldmangled == NULL)
1336 	    {
1337 	      oldmangled = *mangled;
1338 	    }
1339           work->temp_start = -1; /* uppermost call to demangle_class */
1340 	  success = demangle_class (work, mangled, declp);
1341 	  if (success)
1342 	    {
1343 	      remember_type (work, oldmangled, *mangled - oldmangled);
1344 	    }
1345 	  if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1346 	    {
1347               /* EDG and others will have the "F", so we let the loop cycle
1348                  if we are looking at one. */
1349               if (**mangled != 'F')
1350                  expect_func = 1;
1351 	    }
1352 	  oldmangled = NULL;
1353 	  break;
1354 
1355 	case 'B':
1356 	  {
1357 	    string s;
1358 	    success = do_type (work, mangled, &s);
1359 	    if (success)
1360 	      {
1361 		string_append (&s, SCOPE_STRING (work));
1362 		string_prepends (declp, &s);
1363 		string_delete (&s);
1364 	      }
1365 	    oldmangled = NULL;
1366 	    expect_func = 1;
1367 	  }
1368 	  break;
1369 
1370 	case 'F':
1371 	  /* Function */
1372 	  /* ARM/HP style demangling includes a specific 'F' character after
1373 	     the class name.  For GNU style, it is just implied.  So we can
1374 	     safely just consume any 'F' at this point and be compatible
1375 	     with either style.  */
1376 
1377 	  oldmangled = NULL;
1378 	  func_done = 1;
1379 	  (*mangled)++;
1380 
1381 	  /* For lucid/ARM/HP style we have to forget any types we might
1382 	     have remembered up to this point, since they were not argument
1383 	     types.  GNU style considers all types seen as available for
1384 	     back references.  See comment in demangle_args() */
1385 
1386 	  if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1387 	    {
1388 	      forget_types (work);
1389 	    }
1390 	  success = demangle_args (work, mangled, declp);
1391 	  /* After picking off the function args, we expect to either
1392 	     find the function return type (preceded by an '_') or the
1393 	     end of the string. */
1394 	  if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1395 	    {
1396 	      ++(*mangled);
1397               /* At this level, we do not care about the return type. */
1398               success = do_type (work, mangled, &tname);
1399               string_delete (&tname);
1400             }
1401 
1402 	  break;
1403 
1404 	case 't':
1405 	  /* G++ Template */
1406 	  string_init(&trawname);
1407 	  string_init(&tname);
1408 	  if (oldmangled == NULL)
1409 	    {
1410 	      oldmangled = *mangled;
1411 	    }
1412 	  success = demangle_template (work, mangled, &tname,
1413 				       &trawname, 1, 1);
1414 	  if (success)
1415 	    {
1416 	      remember_type (work, oldmangled, *mangled - oldmangled);
1417 	    }
1418 	  string_append (&tname, SCOPE_STRING (work));
1419 
1420 	  string_prepends(declp, &tname);
1421 	  if (work -> destructor & 1)
1422 	    {
1423 	      string_prepend (&trawname, "~");
1424 	      string_appends (declp, &trawname);
1425 	      work->destructor -= 1;
1426 	    }
1427 	  if ((work->constructor & 1) || (work->destructor & 1))
1428 	    {
1429 	      string_appends (declp, &trawname);
1430 	      work->constructor -= 1;
1431 	    }
1432 	  string_delete(&trawname);
1433 	  string_delete(&tname);
1434 	  oldmangled = NULL;
1435 	  expect_func = 1;
1436 	  break;
1437 
1438 	case '_':
1439 	  if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
1440 	    {
1441 	      /* Read the return type. */
1442 	      string return_type;
1443 
1444 	      (*mangled)++;
1445 	      success = do_type (work, mangled, &return_type);
1446 	      APPEND_BLANK (&return_type);
1447 
1448 	      string_prepends (declp, &return_type);
1449 	      string_delete (&return_type);
1450 	      break;
1451 	    }
1452 	  else
1453 	    /* At the outermost level, we cannot have a return type specified,
1454 	       so if we run into another '_' at this point we are dealing with
1455 	       a mangled name that is either bogus, or has been mangled by
1456 	       some algorithm we don't know how to deal with.  So just
1457 	       reject the entire demangling.  */
1458             /* However, "_nnn" is an expected suffix for alternate entry point
1459                numbered nnn for a function, with HP aCC, so skip over that
1460                without reporting failure. pai/1997-09-04 */
1461             if (HP_DEMANGLING)
1462               {
1463                 (*mangled)++;
1464                 while (**mangled && ISDIGIT ((unsigned char)**mangled))
1465                   (*mangled)++;
1466               }
1467             else
1468 	      success = 0;
1469 	  break;
1470 
1471 	case 'H':
1472 	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
1473 	    {
1474 	      /* A G++ template function.  Read the template arguments. */
1475 	      success = demangle_template (work, mangled, declp, 0, 0,
1476 					   0);
1477 	      if (!(work->constructor & 1))
1478 		expect_return_type = 1;
1479 	      (*mangled)++;
1480 	      break;
1481 	    }
1482 	  else
1483 	    /* fall through */
1484 	    {;}
1485 
1486 	default:
1487 	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
1488 	    {
1489 	      /* Assume we have stumbled onto the first outermost function
1490 		 argument token, and start processing args.  */
1491 	      func_done = 1;
1492 	      success = demangle_args (work, mangled, declp);
1493 	    }
1494 	  else
1495 	    {
1496 	      /* Non-GNU demanglers use a specific token to mark the start
1497 		 of the outermost function argument tokens.  Typically 'F',
1498 		 for ARM/HP-demangling, for example.  So if we find something
1499 		 we are not prepared for, it must be an error.  */
1500 	      success = 0;
1501 	    }
1502 	  break;
1503 	}
1504       /*
1505 	if (AUTO_DEMANGLING || GNU_DEMANGLING)
1506 	*/
1507       {
1508 	if (success && expect_func)
1509 	  {
1510 	    func_done = 1;
1511               if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1512                 {
1513                   forget_types (work);
1514                 }
1515 	    success = demangle_args (work, mangled, declp);
1516 	    /* Since template include the mangling of their return types,
1517 	       we must set expect_func to 0 so that we don't try do
1518 	       demangle more arguments the next time we get here.  */
1519 	    expect_func = 0;
1520 	  }
1521       }
1522     }
1523   if (success && !func_done)
1524     {
1525       if (AUTO_DEMANGLING || GNU_DEMANGLING)
1526 	{
1527 	  /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1528 	     bar__3fooi is 'foo::bar(int)'.  We get here when we find the
1529 	     first case, and need to ensure that the '(void)' gets added to
1530 	     the current declp.  Note that with ARM/HP, the first case
1531 	     represents the name of a static data member 'foo::bar',
1532 	     which is in the current declp, so we leave it alone.  */
1533 	  success = demangle_args (work, mangled, declp);
1534 	}
1535     }
1536   if (success && PRINT_ARG_TYPES)
1537     {
1538       if (work->static_type)
1539 	string_append (declp, " static");
1540       if (work->type_quals != TYPE_UNQUALIFIED)
1541 	{
1542 	  APPEND_BLANK (declp);
1543 	  string_append (declp, qualifier_string (work->type_quals));
1544 	}
1545     }
1546 
1547   return (success);
1548 }
1549 
1550 #if 0
1551 
1552 static int
1553 demangle_method_args (struct work_stuff *work, const char **mangled,
1554                       string *declp)
1555 {
1556   int success = 0;
1557 
1558   if (work -> static_type)
1559     {
1560       string_append (declp, *mangled + 1);
1561       *mangled += strlen (*mangled);
1562       success = 1;
1563     }
1564   else
1565     {
1566       success = demangle_args (work, mangled, declp);
1567     }
1568   return (success);
1569 }
1570 
1571 #endif
1572 
1573 static int
demangle_template_template_parm(struct work_stuff * work,const char ** mangled,string * tname)1574 demangle_template_template_parm (struct work_stuff *work,
1575                                  const char **mangled, string *tname)
1576 {
1577   int i;
1578   int r;
1579   int need_comma = 0;
1580   int success = 1;
1581   string temp;
1582 
1583   string_append (tname, "template <");
1584   /* get size of template parameter list */
1585   if (get_count (mangled, &r))
1586     {
1587       for (i = 0; i < r; i++)
1588 	{
1589 	  if (need_comma)
1590 	    {
1591 	      string_append (tname, ", ");
1592 	    }
1593 
1594 	    /* Z for type parameters */
1595 	    if (**mangled == 'Z')
1596 	      {
1597 		(*mangled)++;
1598 		string_append (tname, "class");
1599 	      }
1600 	      /* z for template parameters */
1601 	    else if (**mangled == 'z')
1602 	      {
1603 		(*mangled)++;
1604 		success =
1605 		  demangle_template_template_parm (work, mangled, tname);
1606 		if (!success)
1607 		  {
1608 		    break;
1609 		  }
1610 	      }
1611 	    else
1612 	      {
1613 		/* temp is initialized in do_type */
1614 		success = do_type (work, mangled, &temp);
1615 		if (success)
1616 		  {
1617 		    string_appends (tname, &temp);
1618 		  }
1619 		string_delete(&temp);
1620 		if (!success)
1621 		  {
1622 		    break;
1623 		  }
1624 	      }
1625 	  need_comma = 1;
1626 	}
1627 
1628     }
1629   if (tname->p[-1] == '>')
1630     string_append (tname, " ");
1631   string_append (tname, "> class");
1632   return (success);
1633 }
1634 
1635 static int
demangle_expression(struct work_stuff * work,const char ** mangled,string * s,type_kind_t tk)1636 demangle_expression (struct work_stuff *work, const char **mangled,
1637                      string *s, type_kind_t tk)
1638 {
1639   int need_operator = 0;
1640   int success;
1641 
1642   success = 1;
1643   string_appendn (s, "(", 1);
1644   (*mangled)++;
1645   while (success && **mangled != 'W' && **mangled != '\0')
1646     {
1647       if (need_operator)
1648 	{
1649 	  size_t i;
1650 	  size_t len;
1651 
1652 	  success = 0;
1653 
1654 	  len = strlen (*mangled);
1655 
1656 	  for (i = 0; i < ARRAY_SIZE (optable); ++i)
1657 	    {
1658 	      size_t l = strlen (optable[i].in);
1659 
1660 	      if (l <= len
1661 		  && memcmp (optable[i].in, *mangled, l) == 0)
1662 		{
1663 		  string_appendn (s, " ", 1);
1664 		  string_append (s, optable[i].out);
1665 		  string_appendn (s, " ", 1);
1666 		  success = 1;
1667 		  (*mangled) += l;
1668 		  break;
1669 		}
1670 	    }
1671 
1672 	  if (!success)
1673 	    break;
1674 	}
1675       else
1676 	need_operator = 1;
1677 
1678       success = demangle_template_value_parm (work, mangled, s, tk);
1679     }
1680 
1681   if (**mangled != 'W')
1682     success = 0;
1683   else
1684     {
1685       string_appendn (s, ")", 1);
1686       (*mangled)++;
1687     }
1688 
1689   return success;
1690 }
1691 
1692 static int
demangle_integral_value(struct work_stuff * work,const char ** mangled,string * s)1693 demangle_integral_value (struct work_stuff *work,
1694                          const char **mangled, string *s)
1695 {
1696   int success;
1697 
1698   if (**mangled == 'E')
1699     success = demangle_expression (work, mangled, s, tk_integral);
1700   else if (**mangled == 'Q' || **mangled == 'K')
1701     success = demangle_qualified (work, mangled, s, 0, 1);
1702   else
1703     {
1704       int value;
1705 
1706       /* By default, we let the number decide whether we shall consume an
1707 	 underscore.  */
1708       int multidigit_without_leading_underscore = 0;
1709       int leave_following_underscore = 0;
1710 
1711       success = 0;
1712 
1713       if (**mangled == '_')
1714         {
1715 	  if (mangled[0][1] == 'm')
1716 	    {
1717 	      /* Since consume_count_with_underscores does not handle the
1718 		 `m'-prefix we must do it here, using consume_count and
1719 		 adjusting underscores: we have to consume the underscore
1720 		 matching the prepended one.  */
1721 	      multidigit_without_leading_underscore = 1;
1722 	      string_appendn (s, "-", 1);
1723 	      (*mangled) += 2;
1724 	    }
1725 	  else
1726 	    {
1727 	      /* Do not consume a following underscore;
1728 	         consume_count_with_underscores will consume what
1729 	         should be consumed.  */
1730 	      leave_following_underscore = 1;
1731 	    }
1732 	}
1733       else
1734 	{
1735 	  /* Negative numbers are indicated with a leading `m'.  */
1736 	  if (**mangled == 'm')
1737 	  {
1738 	    string_appendn (s, "-", 1);
1739 	    (*mangled)++;
1740 	  }
1741 	  /* Since consume_count_with_underscores does not handle
1742 	     multi-digit numbers that do not start with an underscore,
1743 	     and this number can be an integer template parameter,
1744 	     we have to call consume_count. */
1745 	  multidigit_without_leading_underscore = 1;
1746 	  /* These multi-digit numbers never end on an underscore,
1747 	     so if there is one then don't eat it. */
1748 	  leave_following_underscore = 1;
1749 	}
1750 
1751       /* We must call consume_count if we expect to remove a trailing
1752 	 underscore, since consume_count_with_underscores expects
1753 	 the leading underscore (that we consumed) if it is to handle
1754 	 multi-digit numbers.  */
1755       if (multidigit_without_leading_underscore)
1756 	value = consume_count (mangled);
1757       else
1758 	value = consume_count_with_underscores (mangled);
1759 
1760       if (value != -1)
1761 	{
1762 	  char buf[INTBUF_SIZE];
1763 	  snprintf (buf, INTBUF_SIZE, "%d", value);
1764 	  string_append (s, buf);
1765 
1766 	  /* Numbers not otherwise delimited, might have an underscore
1767 	     appended as a delimeter, which we should skip.
1768 
1769 	     ??? This used to always remove a following underscore, which
1770 	     is wrong.  If other (arbitrary) cases are followed by an
1771 	     underscore, we need to do something more radical.  */
1772 
1773 	  if ((value > 9 || multidigit_without_leading_underscore)
1774 	      && ! leave_following_underscore
1775 	      && **mangled == '_')
1776 	    (*mangled)++;
1777 
1778 	  /* All is well.  */
1779 	  success = 1;
1780 	}
1781       }
1782 
1783   return success;
1784 }
1785 
1786 /* Demangle the real value in MANGLED.  */
1787 
1788 static int
demangle_real_value(struct work_stuff * work,const char ** mangled,string * s)1789 demangle_real_value (struct work_stuff *work,
1790                      const char **mangled, string *s)
1791 {
1792   if (**mangled == 'E')
1793     return demangle_expression (work, mangled, s, tk_real);
1794 
1795   if (**mangled == 'm')
1796     {
1797       string_appendn (s, "-", 1);
1798       (*mangled)++;
1799     }
1800   while (ISDIGIT ((unsigned char)**mangled))
1801     {
1802       string_appendn (s, *mangled, 1);
1803       (*mangled)++;
1804     }
1805   if (**mangled == '.') /* fraction */
1806     {
1807       string_appendn (s, ".", 1);
1808       (*mangled)++;
1809       while (ISDIGIT ((unsigned char)**mangled))
1810 	{
1811 	  string_appendn (s, *mangled, 1);
1812 	  (*mangled)++;
1813 	}
1814     }
1815   if (**mangled == 'e') /* exponent */
1816     {
1817       string_appendn (s, "e", 1);
1818       (*mangled)++;
1819       while (ISDIGIT ((unsigned char)**mangled))
1820 	{
1821 	  string_appendn (s, *mangled, 1);
1822 	  (*mangled)++;
1823 	}
1824     }
1825 
1826   return 1;
1827 }
1828 
1829 static int
demangle_template_value_parm(struct work_stuff * work,const char ** mangled,string * s,type_kind_t tk)1830 demangle_template_value_parm (struct work_stuff *work, const char **mangled,
1831                               string *s, type_kind_t tk)
1832 {
1833   int success = 1;
1834 
1835   if (**mangled == 'Y')
1836     {
1837       /* The next argument is a template parameter. */
1838       int idx;
1839 
1840       (*mangled)++;
1841       idx = consume_count_with_underscores (mangled);
1842       if (idx == -1
1843 	  || (work->tmpl_argvec && idx >= work->ntmpl_args)
1844 	  || consume_count_with_underscores (mangled) == -1)
1845 	return -1;
1846       if (work->tmpl_argvec)
1847 	string_append (s, work->tmpl_argvec[idx]);
1848       else
1849 	string_append_template_idx (s, idx);
1850     }
1851   else if (tk == tk_integral)
1852     success = demangle_integral_value (work, mangled, s);
1853   else if (tk == tk_char)
1854     {
1855       char tmp[2];
1856       int val;
1857       if (**mangled == 'm')
1858 	{
1859 	  string_appendn (s, "-", 1);
1860 	  (*mangled)++;
1861 	}
1862       string_appendn (s, "'", 1);
1863       val = consume_count(mangled);
1864       if (val <= 0)
1865 	success = 0;
1866       else
1867 	{
1868 	  tmp[0] = (char)val;
1869 	  tmp[1] = '\0';
1870 	  string_appendn (s, &tmp[0], 1);
1871 	  string_appendn (s, "'", 1);
1872 	}
1873     }
1874   else if (tk == tk_bool)
1875     {
1876       int val = consume_count (mangled);
1877       if (val == 0)
1878 	string_appendn (s, "false", 5);
1879       else if (val == 1)
1880 	string_appendn (s, "true", 4);
1881       else
1882 	success = 0;
1883     }
1884   else if (tk == tk_real)
1885     success = demangle_real_value (work, mangled, s);
1886   else if (tk == tk_pointer || tk == tk_reference)
1887     {
1888       if (**mangled == 'Q')
1889 	success = demangle_qualified (work, mangled, s,
1890 				      /*isfuncname=*/0,
1891 				      /*append=*/1);
1892       else
1893 	{
1894 	  int symbol_len  = consume_count (mangled);
1895 	  if (symbol_len == -1)
1896 	    return -1;
1897 	  if (symbol_len == 0)
1898 	    string_appendn (s, "0", 1);
1899 	  else
1900 	    {
1901 	      char *p = XNEWVEC (char, symbol_len + 1), *q;
1902 	      strncpy (p, *mangled, symbol_len);
1903 	      p [symbol_len] = '\0';
1904 	      /* We use cplus_demangle here, rather than
1905 		 internal_cplus_demangle, because the name of the entity
1906 		 mangled here does not make use of any of the squangling
1907 		 or type-code information we have built up thus far; it is
1908 		 mangled independently.  */
1909 	      q = cplus_demangle (p, work->options);
1910 	      if (tk == tk_pointer)
1911 		string_appendn (s, "&", 1);
1912 	      /* FIXME: Pointer-to-member constants should get a
1913 		 qualifying class name here.  */
1914 	      if (q)
1915 		{
1916 		  string_append (s, q);
1917 		  free (q);
1918 		}
1919 	      else
1920 		string_append (s, p);
1921 	      free (p);
1922 	    }
1923 	  *mangled += symbol_len;
1924 	}
1925     }
1926 
1927   return success;
1928 }
1929 
1930 /* Demangle the template name in MANGLED.  The full name of the
1931    template (e.g., S<int>) is placed in TNAME.  The name without the
1932    template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1933    non-NULL.  If IS_TYPE is nonzero, this template is a type template,
1934    not a function template.  If both IS_TYPE and REMEMBER are nonzero,
1935    the template is remembered in the list of back-referenceable
1936    types.  */
1937 
1938 static int
demangle_template(struct work_stuff * work,const char ** mangled,string * tname,string * trawname,int is_type,int remember)1939 demangle_template (struct work_stuff *work, const char **mangled,
1940                    string *tname, string *trawname,
1941                    int is_type, int remember)
1942 {
1943   int i;
1944   int r;
1945   int need_comma = 0;
1946   int success = 0;
1947   int is_java_array = 0;
1948   string temp;
1949 
1950   (*mangled)++;
1951   if (is_type)
1952     {
1953       /* get template name */
1954       if (**mangled == 'z')
1955 	{
1956 	  int idx;
1957 	  (*mangled)++;
1958 	  (*mangled)++;
1959 
1960 	  idx = consume_count_with_underscores (mangled);
1961 	  if (idx == -1
1962 	      || (work->tmpl_argvec && idx >= work->ntmpl_args)
1963 	      || consume_count_with_underscores (mangled) == -1)
1964 	    return (0);
1965 
1966 	  if (work->tmpl_argvec)
1967 	    {
1968 	      string_append (tname, work->tmpl_argvec[idx]);
1969 	      if (trawname)
1970 		string_append (trawname, work->tmpl_argvec[idx]);
1971 	    }
1972 	  else
1973 	    {
1974 	      string_append_template_idx (tname, idx);
1975 	      if (trawname)
1976 		string_append_template_idx (trawname, idx);
1977 	    }
1978 	}
1979       else
1980 	{
1981 	  if ((r = consume_count (mangled)) <= 0
1982 	      || (int) strlen (*mangled) < r)
1983 	    {
1984 	      return (0);
1985 	    }
1986 	  is_java_array = (work -> options & DMGL_JAVA)
1987 	    && strncmp (*mangled, "JArray1Z", 8) == 0;
1988 	  if (! is_java_array)
1989 	    {
1990 	      string_appendn (tname, *mangled, r);
1991 	    }
1992 	  if (trawname)
1993 	    string_appendn (trawname, *mangled, r);
1994 	  *mangled += r;
1995 	}
1996     }
1997   if (!is_java_array)
1998     string_append (tname, "<");
1999   /* get size of template parameter list */
2000   if (!get_count (mangled, &r))
2001     {
2002       return (0);
2003     }
2004   if (!is_type)
2005     {
2006       /* Create an array for saving the template argument values. */
2007       work->tmpl_argvec = XNEWVEC (char *, r);
2008       work->ntmpl_args = r;
2009       for (i = 0; i < r; i++)
2010 	work->tmpl_argvec[i] = 0;
2011     }
2012   for (i = 0; i < r; i++)
2013     {
2014       if (need_comma)
2015 	{
2016 	  string_append (tname, ", ");
2017 	}
2018       /* Z for type parameters */
2019       if (**mangled == 'Z')
2020 	{
2021 	  (*mangled)++;
2022 	  /* temp is initialized in do_type */
2023 	  success = do_type (work, mangled, &temp);
2024 	  if (success)
2025 	    {
2026 	      string_appends (tname, &temp);
2027 
2028 	      if (!is_type)
2029 		{
2030 		  /* Save the template argument. */
2031 		  int len = temp.p - temp.b;
2032 		  work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2033 		  memcpy (work->tmpl_argvec[i], temp.b, len);
2034 		  work->tmpl_argvec[i][len] = '\0';
2035 		}
2036 	    }
2037 	  string_delete(&temp);
2038 	  if (!success)
2039 	    {
2040 	      break;
2041 	    }
2042 	}
2043       /* z for template parameters */
2044       else if (**mangled == 'z')
2045 	{
2046 	  int r2;
2047 	  (*mangled)++;
2048 	  success = demangle_template_template_parm (work, mangled, tname);
2049 
2050 	  if (success
2051 	      && (r2 = consume_count (mangled)) > 0
2052 	      && (int) strlen (*mangled) >= r2)
2053 	    {
2054 	      string_append (tname, " ");
2055 	      string_appendn (tname, *mangled, r2);
2056 	      if (!is_type)
2057 		{
2058 		  /* Save the template argument. */
2059 		  int len = r2;
2060 		  work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2061 		  memcpy (work->tmpl_argvec[i], *mangled, len);
2062 		  work->tmpl_argvec[i][len] = '\0';
2063 		}
2064 	      *mangled += r2;
2065 	    }
2066 	  if (!success)
2067 	    {
2068 	      break;
2069 	    }
2070 	}
2071       else
2072 	{
2073 	  string  param;
2074 	  string* s;
2075 
2076 	  /* otherwise, value parameter */
2077 
2078 	  /* temp is initialized in do_type */
2079 	  success = do_type (work, mangled, &temp);
2080 	  string_delete(&temp);
2081 	  if (!success)
2082 	    break;
2083 
2084 	  if (!is_type)
2085 	    {
2086 	      s = &param;
2087 	      string_init (s);
2088 	    }
2089 	  else
2090 	    s = tname;
2091 
2092 	  success = demangle_template_value_parm (work, mangled, s,
2093 						  (type_kind_t) success);
2094 
2095 	  if (!success)
2096 	    {
2097 	      if (!is_type)
2098 		string_delete (s);
2099 	      success = 0;
2100 	      break;
2101 	    }
2102 
2103 	  if (!is_type)
2104 	    {
2105 	      int len = s->p - s->b;
2106 	      work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2107 	      memcpy (work->tmpl_argvec[i], s->b, len);
2108 	      work->tmpl_argvec[i][len] = '\0';
2109 
2110 	      string_appends (tname, s);
2111 	      string_delete (s);
2112 	    }
2113 	}
2114       need_comma = 1;
2115     }
2116   if (is_java_array)
2117     {
2118       string_append (tname, "[]");
2119     }
2120   else
2121     {
2122       if (tname->p[-1] == '>')
2123 	string_append (tname, " ");
2124       string_append (tname, ">");
2125     }
2126 
2127   if (is_type && remember)
2128     {
2129       const int bindex = register_Btype (work);
2130       remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
2131     }
2132 
2133   /*
2134     if (work -> static_type)
2135     {
2136     string_append (declp, *mangled + 1);
2137     *mangled += strlen (*mangled);
2138     success = 1;
2139     }
2140     else
2141     {
2142     success = demangle_args (work, mangled, declp);
2143     }
2144     }
2145     */
2146   return (success);
2147 }
2148 
2149 static int
arm_pt(struct work_stuff * work,const char * mangled,int n,const char ** anchor,const char ** args)2150 arm_pt (struct work_stuff *work, const char *mangled,
2151         int n, const char **anchor, const char **args)
2152 {
2153   /* Check if ARM template with "__pt__" in it ("parameterized type") */
2154   /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2155   if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__")))
2156     {
2157       int len;
2158       *args = *anchor + 6;
2159       len = consume_count (args);
2160       if (len == -1)
2161 	return 0;
2162       if (*args + len == mangled + n && **args == '_')
2163 	{
2164 	  ++*args;
2165 	  return 1;
2166 	}
2167     }
2168   if (AUTO_DEMANGLING || EDG_DEMANGLING)
2169     {
2170       if ((*anchor = strstr (mangled, "__tm__"))
2171           || (*anchor = strstr (mangled, "__ps__"))
2172           || (*anchor = strstr (mangled, "__pt__")))
2173         {
2174           int len;
2175           *args = *anchor + 6;
2176           len = consume_count (args);
2177 	  if (len == -1)
2178 	    return 0;
2179           if (*args + len == mangled + n && **args == '_')
2180             {
2181               ++*args;
2182               return 1;
2183             }
2184         }
2185       else if ((*anchor = strstr (mangled, "__S")))
2186         {
2187  	  int len;
2188  	  *args = *anchor + 3;
2189  	  len = consume_count (args);
2190 	  if (len == -1)
2191 	    return 0;
2192  	  if (*args + len == mangled + n && **args == '_')
2193             {
2194               ++*args;
2195  	      return 1;
2196             }
2197         }
2198     }
2199 
2200   return 0;
2201 }
2202 
2203 static void
demangle_arm_hp_template(struct work_stuff * work,const char ** mangled,int n,string * declp)2204 demangle_arm_hp_template (struct work_stuff *work, const char **mangled,
2205                           int n, string *declp)
2206 {
2207   const char *p;
2208   const char *args;
2209   const char *e = *mangled + n;
2210   string arg;
2211 
2212   /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2213      template args */
2214   if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
2215     {
2216       char *start_spec_args = NULL;
2217       int hold_options;
2218 
2219       /* First check for and omit template specialization pseudo-arguments,
2220          such as in "Spec<#1,#1.*>" */
2221       start_spec_args = strchr (*mangled, '<');
2222       if (start_spec_args && (start_spec_args - *mangled < n))
2223         string_appendn (declp, *mangled, start_spec_args - *mangled);
2224       else
2225         string_appendn (declp, *mangled, n);
2226       (*mangled) += n + 1;
2227       string_init (&arg);
2228       if (work->temp_start == -1) /* non-recursive call */
2229         work->temp_start = declp->p - declp->b;
2230 
2231       /* We want to unconditionally demangle parameter types in
2232 	 template parameters.  */
2233       hold_options = work->options;
2234       work->options |= DMGL_PARAMS;
2235 
2236       string_append (declp, "<");
2237       while (1)
2238         {
2239           string_delete (&arg);
2240           switch (**mangled)
2241             {
2242               case 'T':
2243                 /* 'T' signals a type parameter */
2244                 (*mangled)++;
2245                 if (!do_type (work, mangled, &arg))
2246                   goto hpacc_template_args_done;
2247                 break;
2248 
2249               case 'U':
2250               case 'S':
2251                 /* 'U' or 'S' signals an integral value */
2252                 if (!do_hpacc_template_const_value (work, mangled, &arg))
2253                   goto hpacc_template_args_done;
2254                 break;
2255 
2256               case 'A':
2257                 /* 'A' signals a named constant expression (literal) */
2258                 if (!do_hpacc_template_literal (work, mangled, &arg))
2259                   goto hpacc_template_args_done;
2260                 break;
2261 
2262               default:
2263                 /* Today, 1997-09-03, we have only the above types
2264                    of template parameters */
2265                 /* FIXME: maybe this should fail and return null */
2266                 goto hpacc_template_args_done;
2267             }
2268           string_appends (declp, &arg);
2269          /* Check if we're at the end of template args.
2270              0 if at end of static member of template class,
2271              _ if done with template args for a function */
2272           if ((**mangled == '\000') || (**mangled == '_'))
2273             break;
2274           else
2275             string_append (declp, ",");
2276         }
2277     hpacc_template_args_done:
2278       string_append (declp, ">");
2279       string_delete (&arg);
2280       if (**mangled == '_')
2281         (*mangled)++;
2282       work->options = hold_options;
2283       return;
2284     }
2285   /* ARM template? (Also handles HP cfront extensions) */
2286   else if (arm_pt (work, *mangled, n, &p, &args))
2287     {
2288       int hold_options;
2289       string type_str;
2290 
2291       string_init (&arg);
2292       string_appendn (declp, *mangled, p - *mangled);
2293       if (work->temp_start == -1)  /* non-recursive call */
2294 	work->temp_start = declp->p - declp->b;
2295 
2296       /* We want to unconditionally demangle parameter types in
2297 	 template parameters.  */
2298       hold_options = work->options;
2299       work->options |= DMGL_PARAMS;
2300 
2301       string_append (declp, "<");
2302       /* should do error checking here */
2303       while (args < e) {
2304 	string_delete (&arg);
2305 
2306 	/* Check for type or literal here */
2307 	switch (*args)
2308 	  {
2309 	    /* HP cfront extensions to ARM for template args */
2310 	    /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2311 	    /* FIXME: We handle only numeric literals for HP cfront */
2312           case 'X':
2313             /* A typed constant value follows */
2314             args++;
2315             if (!do_type (work, &args, &type_str))
2316 	      goto cfront_template_args_done;
2317             string_append (&arg, "(");
2318             string_appends (&arg, &type_str);
2319             string_delete (&type_str);
2320             string_append (&arg, ")");
2321             if (*args != 'L')
2322               goto cfront_template_args_done;
2323             args++;
2324             /* Now snarf a literal value following 'L' */
2325             if (!snarf_numeric_literal (&args, &arg))
2326 	      goto cfront_template_args_done;
2327             break;
2328 
2329           case 'L':
2330             /* Snarf a literal following 'L' */
2331             args++;
2332             if (!snarf_numeric_literal (&args, &arg))
2333 	      goto cfront_template_args_done;
2334             break;
2335           default:
2336             /* Not handling other HP cfront stuff */
2337             {
2338               const char* old_args = args;
2339               if (!do_type (work, &args, &arg))
2340                 goto cfront_template_args_done;
2341 
2342               /* Fail if we didn't make any progress: prevent infinite loop. */
2343               if (args == old_args)
2344 		{
2345 		  work->options = hold_options;
2346 		  return;
2347 		}
2348             }
2349 	  }
2350 	string_appends (declp, &arg);
2351 	string_append (declp, ",");
2352       }
2353     cfront_template_args_done:
2354       string_delete (&arg);
2355       if (args >= e)
2356 	--declp->p; /* remove extra comma */
2357       string_append (declp, ">");
2358       work->options = hold_options;
2359     }
2360   else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2361 	   && (*mangled)[9] == 'N'
2362 	   && (*mangled)[8] == (*mangled)[10]
2363 	   && strchr (cplus_markers, (*mangled)[8]))
2364     {
2365       /* A member of the anonymous namespace.  */
2366       string_append (declp, "{anonymous}");
2367     }
2368   else
2369     {
2370       if (work->temp_start == -1) /* non-recursive call only */
2371 	work->temp_start = 0;     /* disable in recursive calls */
2372       string_appendn (declp, *mangled, n);
2373     }
2374   *mangled += n;
2375 }
2376 
2377 /* Extract a class name, possibly a template with arguments, from the
2378    mangled string; qualifiers, local class indicators, etc. have
2379    already been dealt with */
2380 
2381 static int
demangle_class_name(struct work_stuff * work,const char ** mangled,string * declp)2382 demangle_class_name (struct work_stuff *work, const char **mangled,
2383                      string *declp)
2384 {
2385   int n;
2386   int success = 0;
2387 
2388   n = consume_count (mangled);
2389   if (n == -1)
2390     return 0;
2391   if ((int) strlen (*mangled) >= n)
2392     {
2393       demangle_arm_hp_template (work, mangled, n, declp);
2394       success = 1;
2395     }
2396 
2397   return (success);
2398 }
2399 
2400 /*
2401 
2402 LOCAL FUNCTION
2403 
2404 	demangle_class -- demangle a mangled class sequence
2405 
2406 SYNOPSIS
2407 
2408 	static int
2409 	demangle_class (struct work_stuff *work, const char **mangled,
2410 			strint *declp)
2411 
2412 DESCRIPTION
2413 
2414 	DECLP points to the buffer into which demangling is being done.
2415 
2416 	*MANGLED points to the current token to be demangled.  On input,
2417 	it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2418 	On exit, it points to the next token after the mangled class on
2419 	success, or the first unconsumed token on failure.
2420 
2421 	If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2422 	we are demangling a constructor or destructor.  In this case
2423 	we prepend "class::class" or "class::~class" to DECLP.
2424 
2425 	Otherwise, we prepend "class::" to the current DECLP.
2426 
2427 	Reset the constructor/destructor flags once they have been
2428 	"consumed".  This allows demangle_class to be called later during
2429 	the same demangling, to do normal class demangling.
2430 
2431 	Returns 1 if demangling is successful, 0 otherwise.
2432 
2433 */
2434 
2435 static int
demangle_class(struct work_stuff * work,const char ** mangled,string * declp)2436 demangle_class (struct work_stuff *work, const char **mangled, string *declp)
2437 {
2438   int success = 0;
2439   int btype;
2440   string class_name;
2441   char *save_class_name_end = 0;
2442 
2443   string_init (&class_name);
2444   btype = register_Btype (work);
2445   if (demangle_class_name (work, mangled, &class_name))
2446     {
2447       save_class_name_end = class_name.p;
2448       if ((work->constructor & 1) || (work->destructor & 1))
2449 	{
2450           /* adjust so we don't include template args */
2451           if (work->temp_start && (work->temp_start != -1))
2452             {
2453               class_name.p = class_name.b + work->temp_start;
2454             }
2455 	  string_prepends (declp, &class_name);
2456 	  if (work -> destructor & 1)
2457 	    {
2458 	      string_prepend (declp, "~");
2459               work -> destructor -= 1;
2460 	    }
2461 	  else
2462 	    {
2463 	      work -> constructor -= 1;
2464 	    }
2465 	}
2466       class_name.p = save_class_name_end;
2467       remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2468       remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2469       string_prepend (declp, SCOPE_STRING (work));
2470       string_prepends (declp, &class_name);
2471       success = 1;
2472     }
2473   string_delete (&class_name);
2474   return (success);
2475 }
2476 
2477 
2478 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2479    the rightmost guess.
2480 
2481    Find the correct "__"-sequence where the function name ends and the
2482    signature starts, which is ambiguous with GNU mangling.
2483    Call demangle_signature here, so we can make sure we found the right
2484    one; *mangled will be consumed so caller will not make further calls to
2485    demangle_signature.  */
2486 
2487 static int
iterate_demangle_function(struct work_stuff * work,const char ** mangled,string * declp,const char * scan)2488 iterate_demangle_function (struct work_stuff *work, const char **mangled,
2489                            string *declp, const char *scan)
2490 {
2491   const char *mangle_init = *mangled;
2492   int success = 0;
2493   string decl_init;
2494   struct work_stuff work_init;
2495 
2496   if (*(scan + 2) == '\0')
2497     return 0;
2498 
2499   /* Do not iterate for some demangling modes, or if there's only one
2500      "__"-sequence.  This is the normal case.  */
2501   if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING
2502       || strstr (scan + 2, "__") == NULL)
2503     {
2504       demangle_function_name (work, mangled, declp, scan);
2505       return 1;
2506     }
2507 
2508   /* Save state so we can restart if the guess at the correct "__" was
2509      wrong.  */
2510   string_init (&decl_init);
2511   string_appends (&decl_init, declp);
2512   memset (&work_init, 0, sizeof work_init);
2513   work_stuff_copy_to_from (&work_init, work);
2514 
2515   /* Iterate over occurrences of __, allowing names and types to have a
2516      "__" sequence in them.  We must start with the first (not the last)
2517      occurrence, since "__" most often occur between independent mangled
2518      parts, hence starting at the last occurence inside a signature
2519      might get us a "successful" demangling of the signature.  */
2520 
2521   while (scan[2])
2522     {
2523       demangle_function_name (work, mangled, declp, scan);
2524       success = demangle_signature (work, mangled, declp);
2525       if (success)
2526 	break;
2527 
2528       /* Reset demangle state for the next round.  */
2529       *mangled = mangle_init;
2530       string_clear (declp);
2531       string_appends (declp, &decl_init);
2532       work_stuff_copy_to_from (work, &work_init);
2533 
2534       /* Leave this underscore-sequence.  */
2535       scan += 2;
2536 
2537       /* Scan for the next "__" sequence.  */
2538       while (*scan && (scan[0] != '_' || scan[1] != '_'))
2539 	scan++;
2540 
2541       /* Move to last "__" in this sequence.  */
2542       while (*scan && *scan == '_')
2543 	scan++;
2544       scan -= 2;
2545     }
2546 
2547   /* Delete saved state.  */
2548   delete_work_stuff (&work_init);
2549   string_delete (&decl_init);
2550 
2551   return success;
2552 }
2553 
2554 /*
2555 
2556 LOCAL FUNCTION
2557 
2558 	demangle_prefix -- consume the mangled name prefix and find signature
2559 
2560 SYNOPSIS
2561 
2562 	static int
2563 	demangle_prefix (struct work_stuff *work, const char **mangled,
2564 			 string *declp);
2565 
2566 DESCRIPTION
2567 
2568 	Consume and demangle the prefix of the mangled name.
2569 	While processing the function name root, arrange to call
2570 	demangle_signature if the root is ambiguous.
2571 
2572 	DECLP points to the string buffer into which demangled output is
2573 	placed.  On entry, the buffer is empty.  On exit it contains
2574 	the root function name, the demangled operator name, or in some
2575 	special cases either nothing or the completely demangled result.
2576 
2577 	MANGLED points to the current pointer into the mangled name.  As each
2578 	token of the mangled name is consumed, it is updated.  Upon entry
2579 	the current mangled name pointer points to the first character of
2580 	the mangled name.  Upon exit, it should point to the first character
2581 	of the signature if demangling was successful, or to the first
2582 	unconsumed character if demangling of the prefix was unsuccessful.
2583 
2584 	Returns 1 on success, 0 otherwise.
2585  */
2586 
2587 static int
demangle_prefix(struct work_stuff * work,const char ** mangled,string * declp)2588 demangle_prefix (struct work_stuff *work, const char **mangled,
2589                  string *declp)
2590 {
2591   int success = 1;
2592   const char *scan;
2593   int i;
2594 
2595   if (strlen(*mangled) > 6
2596       && (strncmp(*mangled, "_imp__", 6) == 0
2597           || strncmp(*mangled, "__imp_", 6) == 0))
2598     {
2599       /* it's a symbol imported from a PE dynamic library. Check for both
2600          new style prefix _imp__ and legacy __imp_ used by older versions
2601 	 of dlltool. */
2602       (*mangled) += 6;
2603       work->dllimported = 1;
2604     }
2605   else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2606     {
2607       char *marker = strchr (cplus_markers, (*mangled)[8]);
2608       if (marker != NULL && *marker == (*mangled)[10])
2609 	{
2610 	  if ((*mangled)[9] == 'D')
2611 	    {
2612 	      /* it's a GNU global destructor to be executed at program exit */
2613 	      (*mangled) += 11;
2614 	      work->destructor = 2;
2615 	      if (gnu_special (work, mangled, declp))
2616 		return success;
2617 	    }
2618 	  else if ((*mangled)[9] == 'I')
2619 	    {
2620 	      /* it's a GNU global constructor to be executed at program init */
2621 	      (*mangled) += 11;
2622 	      work->constructor = 2;
2623 	      if (gnu_special (work, mangled, declp))
2624 		return success;
2625 	    }
2626 	}
2627     }
2628   else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2629     {
2630       /* it's a ARM global destructor to be executed at program exit */
2631       (*mangled) += 7;
2632       work->destructor = 2;
2633     }
2634   else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2635     {
2636       /* it's a ARM global constructor to be executed at program initial */
2637       (*mangled) += 7;
2638       work->constructor = 2;
2639     }
2640 
2641   /*  This block of code is a reduction in strength time optimization
2642       of:
2643       scan = strstr (*mangled, "__"); */
2644 
2645   {
2646     scan = *mangled;
2647 
2648     do {
2649       scan = strchr (scan, '_');
2650     } while (scan != NULL && *++scan != '_');
2651 
2652     if (scan != NULL) --scan;
2653   }
2654 
2655   if (scan != NULL)
2656     {
2657       /* We found a sequence of two or more '_', ensure that we start at
2658 	 the last pair in the sequence.  */
2659       i = strspn (scan, "_");
2660       if (i > 2)
2661 	{
2662 	  scan += (i - 2);
2663 	}
2664     }
2665 
2666   if (scan == NULL)
2667     {
2668       success = 0;
2669     }
2670   else if (work -> static_type)
2671     {
2672       if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
2673 	{
2674 	  success = 0;
2675 	}
2676     }
2677   else if ((scan == *mangled)
2678 	   && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
2679 	       || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2680     {
2681       /* The ARM says nothing about the mangling of local variables.
2682 	 But cfront mangles local variables by prepending __<nesting_level>
2683 	 to them. As an extension to ARM demangling we handle this case.  */
2684       if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2685 	  && ISDIGIT ((unsigned char)scan[2]))
2686 	{
2687 	  *mangled = scan + 2;
2688 	  consume_count (mangled);
2689 	  string_append (declp, *mangled);
2690 	  *mangled += strlen (*mangled);
2691 	  success = 1;
2692 	}
2693       else
2694 	{
2695 	  /* A GNU style constructor starts with __[0-9Qt].  But cfront uses
2696 	     names like __Q2_3foo3bar for nested type names.  So don't accept
2697 	     this style of constructor for cfront demangling.  A GNU
2698 	     style member-template constructor starts with 'H'. */
2699 	  if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2700 	    work -> constructor += 1;
2701 	  *mangled = scan + 2;
2702 	}
2703     }
2704   else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2705     {
2706       /* Cfront-style parameterized type.  Handled later as a signature. */
2707       success = 1;
2708 
2709       /* ARM template? */
2710       demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2711     }
2712   else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2713                               || (scan[2] == 'p' && scan[3] == 's')
2714                               || (scan[2] == 'p' && scan[3] == 't')))
2715     {
2716       /* EDG-style parameterized type.  Handled later as a signature. */
2717       success = 1;
2718 
2719       /* EDG template? */
2720       demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2721     }
2722   else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
2723 	   && (scan[2] != 't'))
2724     {
2725       /* Mangled name starts with "__".  Skip over any leading '_' characters,
2726 	 then find the next "__" that separates the prefix from the signature.
2727 	 */
2728       if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2729 	  || (arm_special (mangled, declp) == 0))
2730 	{
2731 	  while (*scan == '_')
2732 	    {
2733 	      scan++;
2734 	    }
2735 	  if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2736 	    {
2737 	      /* No separator (I.E. "__not_mangled"), or empty signature
2738 		 (I.E. "__not_mangled_either__") */
2739 	      success = 0;
2740 	    }
2741 	  else
2742 	    return iterate_demangle_function (work, mangled, declp, scan);
2743 	}
2744     }
2745   else if (*(scan + 2) != '\0')
2746     {
2747       /* Mangled name does not start with "__" but does have one somewhere
2748 	 in there with non empty stuff after it.  Looks like a global
2749 	 function name.  Iterate over all "__":s until the right
2750 	 one is found.  */
2751       return iterate_demangle_function (work, mangled, declp, scan);
2752     }
2753   else
2754     {
2755       /* Doesn't look like a mangled name */
2756       success = 0;
2757     }
2758 
2759   if (!success && (work->constructor == 2 || work->destructor == 2))
2760     {
2761       string_append (declp, *mangled);
2762       *mangled += strlen (*mangled);
2763       success = 1;
2764     }
2765   return (success);
2766 }
2767 
2768 /*
2769 
2770 LOCAL FUNCTION
2771 
2772 	gnu_special -- special handling of gnu mangled strings
2773 
2774 SYNOPSIS
2775 
2776 	static int
2777 	gnu_special (struct work_stuff *work, const char **mangled,
2778 		     string *declp);
2779 
2780 
2781 DESCRIPTION
2782 
2783 	Process some special GNU style mangling forms that don't fit
2784 	the normal pattern.  For example:
2785 
2786 		_$_3foo		(destructor for class foo)
2787 		_vt$foo		(foo virtual table)
2788 		_vt$foo$bar	(foo::bar virtual table)
2789 		__vt_foo	(foo virtual table, new style with thunks)
2790 		_3foo$varname	(static data member)
2791 		_Q22rs2tu$vw	(static data member)
2792 		__t6vector1Zii	(constructor with template)
2793 		__thunk_4__$_7ostream (virtual function thunk)
2794  */
2795 
2796 static int
gnu_special(struct work_stuff * work,const char ** mangled,string * declp)2797 gnu_special (struct work_stuff *work, const char **mangled, string *declp)
2798 {
2799   int n;
2800   int success = 1;
2801   const char *p;
2802 
2803   if ((*mangled)[0] == '_'
2804       && strchr (cplus_markers, (*mangled)[1]) != NULL
2805       && (*mangled)[2] == '_')
2806     {
2807       /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2808       (*mangled) += 3;
2809       work -> destructor += 1;
2810     }
2811   else if ((*mangled)[0] == '_'
2812 	   && (((*mangled)[1] == '_'
2813 		&& (*mangled)[2] == 'v'
2814 		&& (*mangled)[3] == 't'
2815 		&& (*mangled)[4] == '_')
2816 	       || ((*mangled)[1] == 'v'
2817 		   && (*mangled)[2] == 't'
2818 		   && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2819     {
2820       /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2821          and create the decl.  Note that we consume the entire mangled
2822 	 input string, which means that demangle_signature has no work
2823 	 to do.  */
2824       if ((*mangled)[2] == 'v')
2825 	(*mangled) += 5; /* New style, with thunks: "__vt_" */
2826       else
2827 	(*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2828       while (**mangled != '\0')
2829 	{
2830 	  switch (**mangled)
2831 	    {
2832 	    case 'Q':
2833 	    case 'K':
2834 	      success = demangle_qualified (work, mangled, declp, 0, 1);
2835 	      break;
2836 	    case 't':
2837 	      success = demangle_template (work, mangled, declp, 0, 1,
2838 					   1);
2839 	      break;
2840 	    default:
2841 	      if (ISDIGIT((unsigned char)*mangled[0]))
2842 		{
2843 		  n = consume_count(mangled);
2844 		  /* We may be seeing a too-large size, or else a
2845 		     ".<digits>" indicating a static local symbol.  In
2846 		     any case, declare victory and move on; *don't* try
2847 		     to use n to allocate.  */
2848 		  if (n > (int) strlen (*mangled))
2849 		    {
2850 		      success = 1;
2851 		      break;
2852 		    }
2853 		}
2854 	      else
2855 		{
2856 		  n = strcspn (*mangled, cplus_markers);
2857 		}
2858 	      string_appendn (declp, *mangled, n);
2859 	      (*mangled) += n;
2860 	    }
2861 
2862 	  p = strpbrk (*mangled, cplus_markers);
2863 	  if (success && ((p == NULL) || (p == *mangled)))
2864 	    {
2865 	      if (p != NULL)
2866 		{
2867 		  string_append (declp, SCOPE_STRING (work));
2868 		  (*mangled)++;
2869 		}
2870 	    }
2871 	  else
2872 	    {
2873 	      success = 0;
2874 	      break;
2875 	    }
2876 	}
2877       if (success)
2878 	string_append (declp, " virtual table");
2879     }
2880   else if ((*mangled)[0] == '_'
2881 	   && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2882 	   && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2883     {
2884       /* static data member, "_3foo$varname" for example */
2885       (*mangled)++;
2886       switch (**mangled)
2887 	{
2888 	case 'Q':
2889 	case 'K':
2890 	  success = demangle_qualified (work, mangled, declp, 0, 1);
2891 	  break;
2892 	case 't':
2893 	  success = demangle_template (work, mangled, declp, 0, 1, 1);
2894 	  break;
2895 	default:
2896 	  n = consume_count (mangled);
2897 	  if (n < 0 || n > (long) strlen (*mangled))
2898 	    {
2899 	      success = 0;
2900 	      break;
2901 	    }
2902 
2903 	  if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2904 	      && (*mangled)[9] == 'N'
2905 	      && (*mangled)[8] == (*mangled)[10]
2906 	      && strchr (cplus_markers, (*mangled)[8]))
2907 	    {
2908 	      /* A member of the anonymous namespace.  There's information
2909 		 about what identifier or filename it was keyed to, but
2910 		 it's just there to make the mangled name unique; we just
2911 		 step over it.  */
2912 	      string_append (declp, "{anonymous}");
2913 	      (*mangled) += n;
2914 
2915 	      /* Now p points to the marker before the N, so we need to
2916 		 update it to the first marker after what we consumed.  */
2917 	      p = strpbrk (*mangled, cplus_markers);
2918 	      break;
2919 	    }
2920 
2921 	  string_appendn (declp, *mangled, n);
2922 	  (*mangled) += n;
2923 	}
2924       if (success && (p == *mangled))
2925 	{
2926 	  /* Consumed everything up to the cplus_marker, append the
2927 	     variable name.  */
2928 	  (*mangled)++;
2929 	  string_append (declp, SCOPE_STRING (work));
2930 	  n = strlen (*mangled);
2931 	  string_appendn (declp, *mangled, n);
2932 	  (*mangled) += n;
2933 	}
2934       else
2935 	{
2936 	  success = 0;
2937 	}
2938     }
2939   else if (strncmp (*mangled, "__thunk_", 8) == 0)
2940     {
2941       int delta;
2942 
2943       (*mangled) += 8;
2944       delta = consume_count (mangled);
2945       if (delta == -1)
2946 	success = 0;
2947       else
2948 	{
2949 	  char *method = internal_cplus_demangle (work, ++*mangled);
2950 
2951 	  if (method)
2952 	    {
2953 	      char buf[50];
2954 	      snprintf (buf, 50, "virtual function thunk (delta:%d) for ", -delta);
2955 	      string_append (declp, buf);
2956 	      string_append (declp, method);
2957 	      free (method);
2958 	      n = strlen (*mangled);
2959 	      (*mangled) += n;
2960 	    }
2961 	  else
2962 	    {
2963 	      success = 0;
2964 	    }
2965 	}
2966     }
2967   else if (strncmp (*mangled, "__t", 3) == 0
2968 	   && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2969     {
2970       p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2971       (*mangled) += 4;
2972       switch (**mangled)
2973 	{
2974 	case 'Q':
2975 	case 'K':
2976 	  success = demangle_qualified (work, mangled, declp, 0, 1);
2977 	  break;
2978 	case 't':
2979 	  success = demangle_template (work, mangled, declp, 0, 1, 1);
2980 	  break;
2981 	default:
2982 	  success = do_type (work, mangled, declp);
2983 	  break;
2984 	}
2985       if (success && **mangled != '\0')
2986 	success = 0;
2987       if (success)
2988 	string_append (declp, p);
2989     }
2990   else
2991     {
2992       success = 0;
2993     }
2994   return (success);
2995 }
2996 
2997 static void
recursively_demangle(struct work_stuff * work,const char ** mangled,string * result,int namelength)2998 recursively_demangle(struct work_stuff *work, const char **mangled,
2999                      string *result, int namelength)
3000 {
3001   char * recurse = (char *)NULL;
3002   char * recurse_dem = (char *)NULL;
3003 
3004   recurse = XNEWVEC (char, namelength + 1);
3005   memcpy (recurse, *mangled, namelength);
3006   recurse[namelength] = '\000';
3007 
3008   recurse_dem = cplus_demangle (recurse, work->options);
3009 
3010   if (recurse_dem)
3011     {
3012       string_append (result, recurse_dem);
3013       free (recurse_dem);
3014     }
3015   else
3016     {
3017       string_appendn (result, *mangled, namelength);
3018     }
3019   free (recurse);
3020   *mangled += namelength;
3021 }
3022 
3023 /*
3024 
3025 LOCAL FUNCTION
3026 
3027 	arm_special -- special handling of ARM/lucid mangled strings
3028 
3029 SYNOPSIS
3030 
3031 	static int
3032 	arm_special (const char **mangled,
3033 		     string *declp);
3034 
3035 
3036 DESCRIPTION
3037 
3038 	Process some special ARM style mangling forms that don't fit
3039 	the normal pattern.  For example:
3040 
3041 		__vtbl__3foo		(foo virtual table)
3042 		__vtbl__3foo__3bar	(bar::foo virtual table)
3043 
3044  */
3045 
3046 static int
arm_special(const char ** mangled,string * declp)3047 arm_special (const char **mangled, string *declp)
3048 {
3049   int n;
3050   int success = 1;
3051   const char *scan;
3052 
3053   if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
3054     {
3055       /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3056          and create the decl.  Note that we consume the entire mangled
3057 	 input string, which means that demangle_signature has no work
3058 	 to do.  */
3059       scan = *mangled + ARM_VTABLE_STRLEN;
3060       while (*scan != '\0')        /* first check it can be demangled */
3061         {
3062           n = consume_count (&scan);
3063           if (n == -1)
3064 	    {
3065 	      return (0);           /* no good */
3066 	    }
3067           scan += n;
3068           if (scan[0] == '_' && scan[1] == '_')
3069 	    {
3070 	      scan += 2;
3071 	    }
3072         }
3073       (*mangled) += ARM_VTABLE_STRLEN;
3074       while (**mangled != '\0')
3075 	{
3076 	  n = consume_count (mangled);
3077           if (n == -1
3078 	      || n > (long) strlen (*mangled))
3079 	    return 0;
3080 	  string_prependn (declp, *mangled, n);
3081 	  (*mangled) += n;
3082 	  if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
3083 	    {
3084 	      string_prepend (declp, "::");
3085 	      (*mangled) += 2;
3086 	    }
3087 	}
3088       string_append (declp, " virtual table");
3089     }
3090   else
3091     {
3092       success = 0;
3093     }
3094   return (success);
3095 }
3096 
3097 /*
3098 
3099 LOCAL FUNCTION
3100 
3101 	demangle_qualified -- demangle 'Q' qualified name strings
3102 
3103 SYNOPSIS
3104 
3105 	static int
3106 	demangle_qualified (struct work_stuff *, const char *mangled,
3107 			    string *result, int isfuncname, int append);
3108 
3109 DESCRIPTION
3110 
3111 	Demangle a qualified name, such as "Q25Outer5Inner" which is
3112 	the mangled form of "Outer::Inner".  The demangled output is
3113 	prepended or appended to the result string according to the
3114 	state of the append flag.
3115 
3116 	If isfuncname is nonzero, then the qualified name we are building
3117 	is going to be used as a member function name, so if it is a
3118 	constructor or destructor function, append an appropriate
3119 	constructor or destructor name.  I.E. for the above example,
3120 	the result for use as a constructor is "Outer::Inner::Inner"
3121 	and the result for use as a destructor is "Outer::Inner::~Inner".
3122 
3123 BUGS
3124 
3125 	Numeric conversion is ASCII dependent (FIXME).
3126 
3127  */
3128 
3129 static int
demangle_qualified(struct work_stuff * work,const char ** mangled,string * result,int isfuncname,int append)3130 demangle_qualified (struct work_stuff *work, const char **mangled,
3131                     string *result, int isfuncname, int append)
3132 {
3133   int qualifiers = 0;
3134   int success = 1;
3135   char num[2];
3136   string temp;
3137   string last_name;
3138   int bindex = register_Btype (work);
3139 
3140   /* We only make use of ISFUNCNAME if the entity is a constructor or
3141      destructor.  */
3142   isfuncname = (isfuncname
3143 		&& ((work->constructor & 1) || (work->destructor & 1)));
3144 
3145   string_init (&temp);
3146   string_init (&last_name);
3147 
3148   if ((*mangled)[0] == 'K')
3149     {
3150     /* Squangling qualified name reuse */
3151       int idx;
3152       (*mangled)++;
3153       idx = consume_count_with_underscores (mangled);
3154       if (idx == -1 || idx >= work -> numk)
3155         success = 0;
3156       else
3157         string_append (&temp, work -> ktypevec[idx]);
3158     }
3159   else
3160     switch ((*mangled)[1])
3161     {
3162     case '_':
3163       /* GNU mangled name with more than 9 classes.  The count is preceded
3164 	 by an underscore (to distinguish it from the <= 9 case) and followed
3165 	 by an underscore.  */
3166       (*mangled)++;
3167       qualifiers = consume_count_with_underscores (mangled);
3168       if (qualifiers == -1)
3169 	success = 0;
3170       break;
3171 
3172     case '1':
3173     case '2':
3174     case '3':
3175     case '4':
3176     case '5':
3177     case '6':
3178     case '7':
3179     case '8':
3180     case '9':
3181       /* The count is in a single digit.  */
3182       num[0] = (*mangled)[1];
3183       num[1] = '\0';
3184       qualifiers = atoi (num);
3185 
3186       /* If there is an underscore after the digit, skip it.  This is
3187 	 said to be for ARM-qualified names, but the ARM makes no
3188 	 mention of such an underscore.  Perhaps cfront uses one.  */
3189       if ((*mangled)[2] == '_')
3190 	{
3191 	  (*mangled)++;
3192 	}
3193       (*mangled) += 2;
3194       break;
3195 
3196     case '0':
3197     default:
3198       success = 0;
3199     }
3200 
3201   if (!success)
3202     return success;
3203 
3204   /* Pick off the names and collect them in the temp buffer in the order
3205      in which they are found, separated by '::'.  */
3206 
3207   while (qualifiers-- > 0)
3208     {
3209       int remember_K = 1;
3210       string_clear (&last_name);
3211 
3212       if (*mangled[0] == '_')
3213 	(*mangled)++;
3214 
3215       if (*mangled[0] == 't')
3216 	{
3217 	  /* Here we always append to TEMP since we will want to use
3218 	     the template name without the template parameters as a
3219 	     constructor or destructor name.  The appropriate
3220 	     (parameter-less) value is returned by demangle_template
3221 	     in LAST_NAME.  We do not remember the template type here,
3222 	     in order to match the G++ mangling algorithm.  */
3223 	  success = demangle_template(work, mangled, &temp,
3224 				      &last_name, 1, 0);
3225 	  if (!success)
3226 	    break;
3227 	}
3228       else if (*mangled[0] == 'K')
3229 	{
3230           int idx;
3231           (*mangled)++;
3232           idx = consume_count_with_underscores (mangled);
3233           if (idx == -1 || idx >= work->numk)
3234             success = 0;
3235           else
3236             string_append (&temp, work->ktypevec[idx]);
3237           remember_K = 0;
3238 
3239 	  if (!success) break;
3240 	}
3241       else
3242 	{
3243 	  if (EDG_DEMANGLING)
3244             {
3245 	      int namelength;
3246  	      /* Now recursively demangle the qualifier
3247  	       * This is necessary to deal with templates in
3248  	       * mangling styles like EDG */
3249 	      namelength = consume_count (mangled);
3250 	      if (namelength == -1)
3251 		{
3252 		  success = 0;
3253 		  break;
3254 		}
3255  	      recursively_demangle(work, mangled, &temp, namelength);
3256             }
3257           else
3258             {
3259               string_delete (&last_name);
3260               success = do_type (work, mangled, &last_name);
3261               if (!success)
3262                 break;
3263               string_appends (&temp, &last_name);
3264             }
3265 	}
3266 
3267       if (remember_K)
3268 	remember_Ktype (work, temp.b, LEN_STRING (&temp));
3269 
3270       if (qualifiers > 0)
3271 	string_append (&temp, SCOPE_STRING (work));
3272     }
3273 
3274   remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
3275 
3276   /* If we are using the result as a function name, we need to append
3277      the appropriate '::' separated constructor or destructor name.
3278      We do this here because this is the most convenient place, where
3279      we already have a pointer to the name and the length of the name.  */
3280 
3281   if (isfuncname)
3282     {
3283       string_append (&temp, SCOPE_STRING (work));
3284       if (work -> destructor & 1)
3285 	string_append (&temp, "~");
3286       string_appends (&temp, &last_name);
3287     }
3288 
3289   /* Now either prepend the temp buffer to the result, or append it,
3290      depending upon the state of the append flag.  */
3291 
3292   if (append)
3293     string_appends (result, &temp);
3294   else
3295     {
3296       if (!STRING_EMPTY (result))
3297 	string_append (&temp, SCOPE_STRING (work));
3298       string_prepends (result, &temp);
3299     }
3300 
3301   string_delete (&last_name);
3302   string_delete (&temp);
3303   return (success);
3304 }
3305 
3306 /*
3307 
3308 LOCAL FUNCTION
3309 
3310 	get_count -- convert an ascii count to integer, consuming tokens
3311 
3312 SYNOPSIS
3313 
3314 	static int
3315 	get_count (const char **type, int *count)
3316 
3317 DESCRIPTION
3318 
3319 	Assume that *type points at a count in a mangled name; set
3320 	*count to its value, and set *type to the next character after
3321 	the count.  There are some weird rules in effect here.
3322 
3323 	If *type does not point at a string of digits, return zero.
3324 
3325 	If *type points at a string of digits followed by an
3326 	underscore, set *count to their value as an integer, advance
3327 	*type to point *after the underscore, and return 1.
3328 
3329 	If *type points at a string of digits not followed by an
3330 	underscore, consume only the first digit.  Set *count to its
3331 	value as an integer, leave *type pointing after that digit,
3332 	and return 1.
3333 
3334         The excuse for this odd behavior: in the ARM and HP demangling
3335         styles, a type can be followed by a repeat count of the form
3336         `Nxy', where:
3337 
3338         `x' is a single digit specifying how many additional copies
3339             of the type to append to the argument list, and
3340 
3341         `y' is one or more digits, specifying the zero-based index of
3342             the first repeated argument in the list.  Yes, as you're
3343             unmangling the name you can figure this out yourself, but
3344             it's there anyway.
3345 
3346         So, for example, in `bar__3fooFPiN51', the first argument is a
3347         pointer to an integer (`Pi'), and then the next five arguments
3348         are the same (`N5'), and the first repeat is the function's
3349         second argument (`1').
3350 */
3351 
3352 static int
get_count(const char ** type,int * count)3353 get_count (const char **type, int *count)
3354 {
3355   const char *p;
3356   int n;
3357 
3358   if (!ISDIGIT ((unsigned char)**type))
3359     return (0);
3360   else
3361     {
3362       *count = **type - '0';
3363       (*type)++;
3364       if (ISDIGIT ((unsigned char)**type))
3365 	{
3366 	  p = *type;
3367 	  n = *count;
3368 	  do
3369 	    {
3370 	      n *= 10;
3371 	      n += *p - '0';
3372 	      p++;
3373 	    }
3374 	  while (ISDIGIT ((unsigned char)*p));
3375 	  if (*p == '_')
3376 	    {
3377 	      *type = p + 1;
3378 	      *count = n;
3379 	    }
3380 	}
3381     }
3382   return (1);
3383 }
3384 
3385 /* RESULT will be initialised here; it will be freed on failure.  The
3386    value returned is really a type_kind_t.  */
3387 
3388 static int
do_type(struct work_stuff * work,const char ** mangled,string * result)3389 do_type (struct work_stuff *work, const char **mangled, string *result)
3390 {
3391   int n;
3392   int done;
3393   int success;
3394   string decl;
3395   const char *remembered_type;
3396   int type_quals;
3397   type_kind_t tk = tk_none;
3398 
3399   string_init (&decl);
3400   string_init (result);
3401 
3402   done = 0;
3403   success = 1;
3404   while (success && !done)
3405     {
3406       int member;
3407       switch (**mangled)
3408 	{
3409 
3410 	  /* A pointer type */
3411 	case 'P':
3412 	case 'p':
3413 	  (*mangled)++;
3414 	  if (! (work -> options & DMGL_JAVA))
3415 	    string_prepend (&decl, "*");
3416 	  if (tk == tk_none)
3417 	    tk = tk_pointer;
3418 	  break;
3419 
3420 	  /* A reference type */
3421 	case 'R':
3422 	  (*mangled)++;
3423 	  string_prepend (&decl, "&");
3424 	  if (tk == tk_none)
3425 	    tk = tk_reference;
3426 	  break;
3427 
3428 	  /* An array */
3429 	case 'A':
3430 	  {
3431 	    ++(*mangled);
3432 	    if (!STRING_EMPTY (&decl)
3433 		&& (decl.b[0] == '*' || decl.b[0] == '&'))
3434 	      {
3435 		string_prepend (&decl, "(");
3436 		string_append (&decl, ")");
3437 	      }
3438 	    string_append (&decl, "[");
3439 	    if (**mangled != '_')
3440 	      success = demangle_template_value_parm (work, mangled, &decl,
3441 						      tk_integral);
3442 	    if (**mangled == '_')
3443 	      ++(*mangled);
3444 	    string_append (&decl, "]");
3445 	    break;
3446 	  }
3447 
3448 	/* A back reference to a previously seen type */
3449 	case 'T':
3450 	  (*mangled)++;
3451 	  if (!get_count (mangled, &n) || n >= work -> ntypes)
3452 	    {
3453 	      success = 0;
3454 	    }
3455 	  else
3456 	    {
3457 	      remembered_type = work -> typevec[n];
3458 	      mangled = &remembered_type;
3459 	    }
3460 	  break;
3461 
3462 	  /* A function */
3463 	case 'F':
3464 	  (*mangled)++;
3465 	    if (!STRING_EMPTY (&decl)
3466 		&& (decl.b[0] == '*' || decl.b[0] == '&'))
3467 	    {
3468 	      string_prepend (&decl, "(");
3469 	      string_append (&decl, ")");
3470 	    }
3471 	  /* After picking off the function args, we expect to either find the
3472 	     function return type (preceded by an '_') or the end of the
3473 	     string.  */
3474 	  if (!demangle_nested_args (work, mangled, &decl)
3475 	      || (**mangled != '_' && **mangled != '\0'))
3476 	    {
3477 	      success = 0;
3478 	      break;
3479 	    }
3480 	  if (success && (**mangled == '_'))
3481 	    (*mangled)++;
3482 	  break;
3483 
3484 	case 'M':
3485 	case 'O':
3486 	  {
3487 	    type_quals = TYPE_UNQUALIFIED;
3488 
3489 	    member = **mangled == 'M';
3490 	    (*mangled)++;
3491 
3492 	    string_append (&decl, ")");
3493 
3494 	    /* We don't need to prepend `::' for a qualified name;
3495 	       demangle_qualified will do that for us.  */
3496 	    if (**mangled != 'Q')
3497 	      string_prepend (&decl, SCOPE_STRING (work));
3498 
3499 	    if (ISDIGIT ((unsigned char)**mangled))
3500 	      {
3501 		n = consume_count (mangled);
3502 		if (n == -1
3503 		    || (int) strlen (*mangled) < n)
3504 		  {
3505 		    success = 0;
3506 		    break;
3507 		  }
3508 		string_prependn (&decl, *mangled, n);
3509 		*mangled += n;
3510 	      }
3511 	    else if (**mangled == 'X' || **mangled == 'Y')
3512 	      {
3513 		string temp;
3514 		do_type (work, mangled, &temp);
3515 		string_prepends (&decl, &temp);
3516 		string_delete (&temp);
3517 	      }
3518 	    else if (**mangled == 't')
3519 	      {
3520 		string temp;
3521 		string_init (&temp);
3522 		success = demangle_template (work, mangled, &temp,
3523 					     NULL, 1, 1);
3524 		if (success)
3525 		  {
3526 		    string_prependn (&decl, temp.b, temp.p - temp.b);
3527 		    string_delete (&temp);
3528 		  }
3529 		else
3530 		  break;
3531 	      }
3532 	    else if (**mangled == 'Q')
3533 	      {
3534 		success = demangle_qualified (work, mangled, &decl,
3535 					      /*isfuncnam=*/0,
3536 					      /*append=*/0);
3537 		if (!success)
3538 		  break;
3539 	      }
3540 	    else
3541 	      {
3542 		success = 0;
3543 		break;
3544 	      }
3545 
3546 	    string_prepend (&decl, "(");
3547 	    if (member)
3548 	      {
3549 		switch (**mangled)
3550 		  {
3551 		  case 'C':
3552 		  case 'V':
3553 		  case 'u':
3554 		    type_quals |= code_for_qualifier (**mangled);
3555 		    (*mangled)++;
3556 		    break;
3557 
3558 		  default:
3559 		    break;
3560 		  }
3561 
3562 		if (*(*mangled)++ != 'F')
3563 		  {
3564 		    success = 0;
3565 		    break;
3566 		  }
3567 	      }
3568 	    if ((member && !demangle_nested_args (work, mangled, &decl))
3569 		|| **mangled != '_')
3570 	      {
3571 		success = 0;
3572 		break;
3573 	      }
3574 	    (*mangled)++;
3575 	    if (! PRINT_ANSI_QUALIFIERS)
3576 	      {
3577 		break;
3578 	      }
3579 	    if (type_quals != TYPE_UNQUALIFIED)
3580 	      {
3581 		APPEND_BLANK (&decl);
3582 		string_append (&decl, qualifier_string (type_quals));
3583 	      }
3584 	    break;
3585 	  }
3586         case 'G':
3587 	  (*mangled)++;
3588 	  break;
3589 
3590 	case 'C':
3591 	case 'V':
3592 	case 'u':
3593 	  if (PRINT_ANSI_QUALIFIERS)
3594 	    {
3595 	      if (!STRING_EMPTY (&decl))
3596 		string_prepend (&decl, " ");
3597 
3598 	      string_prepend (&decl, demangle_qualifier (**mangled));
3599 	    }
3600 	  (*mangled)++;
3601 	  break;
3602 	  /*
3603 	    }
3604 	    */
3605 
3606 	  /* fall through */
3607 	default:
3608 	  done = 1;
3609 	  break;
3610 	}
3611     }
3612 
3613   if (success) switch (**mangled)
3614     {
3615       /* A qualified name, such as "Outer::Inner".  */
3616     case 'Q':
3617     case 'K':
3618       {
3619         success = demangle_qualified (work, mangled, result, 0, 1);
3620         break;
3621       }
3622 
3623     /* A back reference to a previously seen squangled type */
3624     case 'B':
3625       (*mangled)++;
3626       if (!get_count (mangled, &n) || n >= work -> numb)
3627 	success = 0;
3628       else
3629 	string_append (result, work->btypevec[n]);
3630       break;
3631 
3632     case 'X':
3633     case 'Y':
3634       /* A template parm.  We substitute the corresponding argument. */
3635       {
3636 	int idx;
3637 
3638 	(*mangled)++;
3639 	idx = consume_count_with_underscores (mangled);
3640 
3641 	if (idx == -1
3642 	    || (work->tmpl_argvec && idx >= work->ntmpl_args)
3643 	    || consume_count_with_underscores (mangled) == -1)
3644 	  {
3645 	    success = 0;
3646 	    break;
3647 	  }
3648 
3649 	if (work->tmpl_argvec)
3650 	  string_append (result, work->tmpl_argvec[idx]);
3651 	else
3652 	  string_append_template_idx (result, idx);
3653 
3654 	success = 1;
3655       }
3656     break;
3657 
3658     default:
3659       success = demangle_fund_type (work, mangled, result);
3660       if (tk == tk_none)
3661 	tk = (type_kind_t) success;
3662       break;
3663     }
3664 
3665   if (success)
3666     {
3667       if (!STRING_EMPTY (&decl))
3668 	{
3669 	  string_append (result, " ");
3670 	  string_appends (result, &decl);
3671 	}
3672     }
3673   else
3674     string_delete (result);
3675   string_delete (&decl);
3676 
3677   if (success)
3678     /* Assume an integral type, if we're not sure.  */
3679     return (int) ((tk == tk_none) ? tk_integral : tk);
3680   else
3681     return 0;
3682 }
3683 
3684 /* Given a pointer to a type string that represents a fundamental type
3685    argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3686    string in which the demangled output is being built in RESULT, and
3687    the WORK structure, decode the types and add them to the result.
3688 
3689    For example:
3690 
3691    	"Ci"	=>	"const int"
3692 	"Sl"	=>	"signed long"
3693 	"CUs"	=>	"const unsigned short"
3694 
3695    The value returned is really a type_kind_t.  */
3696 
3697 static int
demangle_fund_type(struct work_stuff * work,const char ** mangled,string * result)3698 demangle_fund_type (struct work_stuff *work,
3699                     const char **mangled, string *result)
3700 {
3701   int done = 0;
3702   int success = 1;
3703   char buf[10];
3704   unsigned int dec = 0;
3705   type_kind_t tk = tk_integral;
3706 
3707   /* First pick off any type qualifiers.  There can be more than one.  */
3708 
3709   while (!done)
3710     {
3711       switch (**mangled)
3712 	{
3713 	case 'C':
3714 	case 'V':
3715 	case 'u':
3716 	  if (PRINT_ANSI_QUALIFIERS)
3717 	    {
3718               if (!STRING_EMPTY (result))
3719                 string_prepend (result, " ");
3720 	      string_prepend (result, demangle_qualifier (**mangled));
3721 	    }
3722 	  (*mangled)++;
3723 	  break;
3724 	case 'U':
3725 	  (*mangled)++;
3726 	  APPEND_BLANK (result);
3727 	  string_append (result, "unsigned");
3728 	  break;
3729 	case 'S': /* signed char only */
3730 	  (*mangled)++;
3731 	  APPEND_BLANK (result);
3732 	  string_append (result, "signed");
3733 	  break;
3734 	case 'J':
3735 	  (*mangled)++;
3736 	  APPEND_BLANK (result);
3737 	  string_append (result, "__complex");
3738 	  break;
3739 	default:
3740 	  done = 1;
3741 	  break;
3742 	}
3743     }
3744 
3745   /* Now pick off the fundamental type.  There can be only one.  */
3746 
3747   switch (**mangled)
3748     {
3749     case '\0':
3750     case '_':
3751       break;
3752     case 'v':
3753       (*mangled)++;
3754       APPEND_BLANK (result);
3755       string_append (result, "void");
3756       break;
3757     case 'x':
3758       (*mangled)++;
3759       APPEND_BLANK (result);
3760       string_append (result, "long long");
3761       break;
3762     case 'l':
3763       (*mangled)++;
3764       APPEND_BLANK (result);
3765       string_append (result, "long");
3766       break;
3767     case 'i':
3768       (*mangled)++;
3769       APPEND_BLANK (result);
3770       string_append (result, "int");
3771       break;
3772     case 's':
3773       (*mangled)++;
3774       APPEND_BLANK (result);
3775       string_append (result, "short");
3776       break;
3777     case 'b':
3778       (*mangled)++;
3779       APPEND_BLANK (result);
3780       string_append (result, "bool");
3781       tk = tk_bool;
3782       break;
3783     case 'c':
3784       (*mangled)++;
3785       APPEND_BLANK (result);
3786       string_append (result, "char");
3787       tk = tk_char;
3788       break;
3789     case 'w':
3790       (*mangled)++;
3791       APPEND_BLANK (result);
3792       string_append (result, "wchar_t");
3793       tk = tk_char;
3794       break;
3795     case 'r':
3796       (*mangled)++;
3797       APPEND_BLANK (result);
3798       string_append (result, "long double");
3799       tk = tk_real;
3800       break;
3801     case 'd':
3802       (*mangled)++;
3803       APPEND_BLANK (result);
3804       string_append (result, "double");
3805       tk = tk_real;
3806       break;
3807     case 'f':
3808       (*mangled)++;
3809       APPEND_BLANK (result);
3810       string_append (result, "float");
3811       tk = tk_real;
3812       break;
3813     case 'G':
3814       (*mangled)++;
3815       if (!ISDIGIT ((unsigned char)**mangled))
3816 	{
3817 	  success = 0;
3818 	  break;
3819 	}
3820     case 'I':
3821       (*mangled)++;
3822       if (**mangled == '_')
3823 	{
3824 	  int i;
3825 	  (*mangled)++;
3826 	  for (i = 0;
3827 	       i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
3828 	       (*mangled)++, i++)
3829 	    buf[i] = **mangled;
3830 	  if (**mangled != '_')
3831 	    {
3832 	      success = 0;
3833 	      break;
3834 	    }
3835 	  buf[i] = '\0';
3836 	  (*mangled)++;
3837 	}
3838       else
3839 	{
3840 	  strncpy (buf, *mangled, 2);
3841 	  buf[2] = '\0';
3842 	  *mangled += min (strlen (*mangled), 2);
3843 	}
3844       sscanf (buf, "%x", &dec);
3845       snprintf (buf, 10, "int%u_t", dec);
3846       APPEND_BLANK (result);
3847       string_append (result, buf);
3848       break;
3849 
3850       /* fall through */
3851       /* An explicit type, such as "6mytype" or "7integer" */
3852     case '0':
3853     case '1':
3854     case '2':
3855     case '3':
3856     case '4':
3857     case '5':
3858     case '6':
3859     case '7':
3860     case '8':
3861     case '9':
3862       {
3863         int bindex = register_Btype (work);
3864         string btype;
3865         string_init (&btype);
3866         if (demangle_class_name (work, mangled, &btype)) {
3867           remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3868           APPEND_BLANK (result);
3869           string_appends (result, &btype);
3870         }
3871         else
3872           success = 0;
3873         string_delete (&btype);
3874         break;
3875       }
3876     case 't':
3877       {
3878         string btype;
3879         string_init (&btype);
3880         success = demangle_template (work, mangled, &btype, 0, 1, 1);
3881         string_appends (result, &btype);
3882         string_delete (&btype);
3883         break;
3884       }
3885     default:
3886       success = 0;
3887       break;
3888     }
3889 
3890   return success ? ((int) tk) : 0;
3891 }
3892 
3893 
3894 /* Handle a template's value parameter for HP aCC (extension from ARM)
3895    **mangled points to 'S' or 'U' */
3896 
3897 static int
do_hpacc_template_const_value(struct work_stuff * work ATTRIBUTE_UNUSED,const char ** mangled,string * result)3898 do_hpacc_template_const_value (struct work_stuff *work ATTRIBUTE_UNUSED,
3899                                const char **mangled, string *result)
3900 {
3901   int unsigned_const;
3902 
3903   if (**mangled != 'U' && **mangled != 'S')
3904     return 0;
3905 
3906   unsigned_const = (**mangled == 'U');
3907 
3908   (*mangled)++;
3909 
3910   switch (**mangled)
3911     {
3912       case 'N':
3913         string_append (result, "-");
3914         /* fall through */
3915       case 'P':
3916         (*mangled)++;
3917         break;
3918       case 'M':
3919         /* special case for -2^31 */
3920         string_append (result, "-2147483648");
3921         (*mangled)++;
3922         return 1;
3923       default:
3924         return 0;
3925     }
3926 
3927   /* We have to be looking at an integer now */
3928   if (!(ISDIGIT ((unsigned char)**mangled)))
3929     return 0;
3930 
3931   /* We only deal with integral values for template
3932      parameters -- so it's OK to look only for digits */
3933   while (ISDIGIT ((unsigned char)**mangled))
3934     {
3935       char_str[0] = **mangled;
3936       string_append (result, char_str);
3937       (*mangled)++;
3938     }
3939 
3940   if (unsigned_const)
3941     string_append (result, "U");
3942 
3943   /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3944      with L or LL suffixes. pai/1997-09-03 */
3945 
3946   return 1; /* success */
3947 }
3948 
3949 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3950    **mangled is pointing to the 'A' */
3951 
3952 static int
do_hpacc_template_literal(struct work_stuff * work,const char ** mangled,string * result)3953 do_hpacc_template_literal (struct work_stuff *work, const char **mangled,
3954                            string *result)
3955 {
3956   int literal_len = 0;
3957   char * recurse;
3958   char * recurse_dem;
3959 
3960   if (**mangled != 'A')
3961     return 0;
3962 
3963   (*mangled)++;
3964 
3965   literal_len = consume_count (mangled);
3966 
3967   if (literal_len <= 0)
3968     return 0;
3969 
3970   /* Literal parameters are names of arrays, functions, etc.  and the
3971      canonical representation uses the address operator */
3972   string_append (result, "&");
3973 
3974   /* Now recursively demangle the literal name */
3975   recurse = XNEWVEC (char, literal_len + 1);
3976   memcpy (recurse, *mangled, literal_len);
3977   recurse[literal_len] = '\000';
3978 
3979   recurse_dem = cplus_demangle (recurse, work->options);
3980 
3981   if (recurse_dem)
3982     {
3983       string_append (result, recurse_dem);
3984       free (recurse_dem);
3985     }
3986   else
3987     {
3988       string_appendn (result, *mangled, literal_len);
3989     }
3990   (*mangled) += literal_len;
3991   free (recurse);
3992 
3993   return 1;
3994 }
3995 
3996 static int
snarf_numeric_literal(const char ** args,string * arg)3997 snarf_numeric_literal (const char **args, string *arg)
3998 {
3999   if (**args == '-')
4000     {
4001       char_str[0] = '-';
4002       string_append (arg, char_str);
4003       (*args)++;
4004     }
4005   else if (**args == '+')
4006     (*args)++;
4007 
4008   if (!ISDIGIT ((unsigned char)**args))
4009     return 0;
4010 
4011   while (ISDIGIT ((unsigned char)**args))
4012     {
4013       char_str[0] = **args;
4014       string_append (arg, char_str);
4015       (*args)++;
4016     }
4017 
4018   return 1;
4019 }
4020 
4021 /* Demangle the next argument, given by MANGLED into RESULT, which
4022    *should be an uninitialized* string.  It will be initialized here,
4023    and free'd should anything go wrong.  */
4024 
4025 static int
do_arg(struct work_stuff * work,const char ** mangled,string * result)4026 do_arg (struct work_stuff *work, const char **mangled, string *result)
4027 {
4028   /* Remember where we started so that we can record the type, for
4029      non-squangling type remembering.  */
4030   const char *start = *mangled;
4031 
4032   string_init (result);
4033 
4034   if (work->nrepeats > 0)
4035     {
4036       --work->nrepeats;
4037 
4038       if (work->previous_argument == 0)
4039 	return 0;
4040 
4041       /* We want to reissue the previous type in this argument list.  */
4042       string_appends (result, work->previous_argument);
4043       return 1;
4044     }
4045 
4046   if (**mangled == 'n')
4047     {
4048       /* A squangling-style repeat.  */
4049       (*mangled)++;
4050       work->nrepeats = consume_count(mangled);
4051 
4052       if (work->nrepeats <= 0)
4053 	/* This was not a repeat count after all.  */
4054 	return 0;
4055 
4056       if (work->nrepeats > 9)
4057 	{
4058 	  if (**mangled != '_')
4059 	    /* The repeat count should be followed by an '_' in this
4060 	       case.  */
4061 	    return 0;
4062 	  else
4063 	    (*mangled)++;
4064 	}
4065 
4066       /* Now, the repeat is all set up.  */
4067       return do_arg (work, mangled, result);
4068     }
4069 
4070   /* Save the result in WORK->previous_argument so that we can find it
4071      if it's repeated.  Note that saving START is not good enough: we
4072      do not want to add additional types to the back-referenceable
4073      type vector when processing a repeated type.  */
4074   if (work->previous_argument)
4075     string_delete (work->previous_argument);
4076   else
4077     work->previous_argument = XNEW (string);
4078 
4079   if (!do_type (work, mangled, work->previous_argument))
4080     return 0;
4081 
4082   string_appends (result, work->previous_argument);
4083 
4084   remember_type (work, start, *mangled - start);
4085   return 1;
4086 }
4087 
4088 static void
remember_type(struct work_stuff * work,const char * start,int len)4089 remember_type (struct work_stuff *work, const char *start, int len)
4090 {
4091   char *tem;
4092 
4093   if (work->forgetting_types)
4094     return;
4095 
4096   if (work -> ntypes >= work -> typevec_size)
4097     {
4098       if (work -> typevec_size == 0)
4099 	{
4100 	  work -> typevec_size = 3;
4101 	  work -> typevec = XNEWVEC (char *, work->typevec_size);
4102 	}
4103       else
4104 	{
4105 	  work -> typevec_size *= 2;
4106 	  work -> typevec
4107 	    = XRESIZEVEC (char *, work->typevec, work->typevec_size);
4108 	}
4109     }
4110   tem = XNEWVEC (char, len + 1);
4111   memcpy (tem, start, len);
4112   tem[len] = '\0';
4113   work -> typevec[work -> ntypes++] = tem;
4114 }
4115 
4116 
4117 /* Remember a K type class qualifier. */
4118 static void
remember_Ktype(struct work_stuff * work,const char * start,int len)4119 remember_Ktype (struct work_stuff *work, const char *start, int len)
4120 {
4121   char *tem;
4122 
4123   if (work -> numk >= work -> ksize)
4124     {
4125       if (work -> ksize == 0)
4126 	{
4127 	  work -> ksize = 5;
4128 	  work -> ktypevec = XNEWVEC (char *, work->ksize);
4129 	}
4130       else
4131 	{
4132 	  work -> ksize *= 2;
4133 	  work -> ktypevec
4134 	    = XRESIZEVEC (char *, work->ktypevec, work->ksize);
4135 	}
4136     }
4137   tem = XNEWVEC (char, len + 1);
4138   memcpy (tem, start, len);
4139   tem[len] = '\0';
4140   work -> ktypevec[work -> numk++] = tem;
4141 }
4142 
4143 /* Register a B code, and get an index for it. B codes are registered
4144    as they are seen, rather than as they are completed, so map<temp<char> >
4145    registers map<temp<char> > as B0, and temp<char> as B1 */
4146 
4147 static int
register_Btype(struct work_stuff * work)4148 register_Btype (struct work_stuff *work)
4149 {
4150   int ret;
4151 
4152   if (work -> numb >= work -> bsize)
4153     {
4154       if (work -> bsize == 0)
4155 	{
4156 	  work -> bsize = 5;
4157 	  work -> btypevec = XNEWVEC (char *, work->bsize);
4158 	}
4159       else
4160 	{
4161 	  work -> bsize *= 2;
4162 	  work -> btypevec
4163 	    = XRESIZEVEC (char *, work->btypevec, work->bsize);
4164 	}
4165     }
4166   ret = work -> numb++;
4167   work -> btypevec[ret] = NULL;
4168   return(ret);
4169 }
4170 
4171 /* Store a value into a previously registered B code type. */
4172 
4173 static void
remember_Btype(struct work_stuff * work,const char * start,int len,int index)4174 remember_Btype (struct work_stuff *work, const char *start,
4175                 int len, int index)
4176 {
4177   char *tem;
4178 
4179   tem = XNEWVEC (char, len + 1);
4180   memcpy (tem, start, len);
4181   tem[len] = '\0';
4182   work -> btypevec[index] = tem;
4183 }
4184 
4185 /* Lose all the info related to B and K type codes. */
4186 static void
forget_B_and_K_types(struct work_stuff * work)4187 forget_B_and_K_types (struct work_stuff *work)
4188 {
4189   int i;
4190 
4191   while (work -> numk > 0)
4192     {
4193       i = --(work -> numk);
4194       if (work -> ktypevec[i] != NULL)
4195 	{
4196 	  free (work -> ktypevec[i]);
4197 	  work -> ktypevec[i] = NULL;
4198 	}
4199     }
4200 
4201   while (work -> numb > 0)
4202     {
4203       i = --(work -> numb);
4204       if (work -> btypevec[i] != NULL)
4205 	{
4206 	  free (work -> btypevec[i]);
4207 	  work -> btypevec[i] = NULL;
4208 	}
4209     }
4210 }
4211 /* Forget the remembered types, but not the type vector itself.  */
4212 
4213 static void
forget_types(struct work_stuff * work)4214 forget_types (struct work_stuff *work)
4215 {
4216   int i;
4217 
4218   while (work -> ntypes > 0)
4219     {
4220       i = --(work -> ntypes);
4221       if (work -> typevec[i] != NULL)
4222 	{
4223 	  free (work -> typevec[i]);
4224 	  work -> typevec[i] = NULL;
4225 	}
4226     }
4227 }
4228 
4229 /* Process the argument list part of the signature, after any class spec
4230    has been consumed, as well as the first 'F' character (if any).  For
4231    example:
4232 
4233    "__als__3fooRT0"		=>	process "RT0"
4234    "complexfunc5__FPFPc_PFl_i"	=>	process "PFPc_PFl_i"
4235 
4236    DECLP must be already initialised, usually non-empty.  It won't be freed
4237    on failure.
4238 
4239    Note that g++ differs significantly from ARM and lucid style mangling
4240    with regards to references to previously seen types.  For example, given
4241    the source fragment:
4242 
4243      class foo {
4244        public:
4245        foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4246      };
4247 
4248      foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4249      void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4250 
4251    g++ produces the names:
4252 
4253      __3fooiRT0iT2iT2
4254      foo__FiR3fooiT1iT1
4255 
4256    while lcc (and presumably other ARM style compilers as well) produces:
4257 
4258      foo__FiR3fooT1T2T1T2
4259      __ct__3fooFiR3fooT1T2T1T2
4260 
4261    Note that g++ bases its type numbers starting at zero and counts all
4262    previously seen types, while lucid/ARM bases its type numbers starting
4263    at one and only considers types after it has seen the 'F' character
4264    indicating the start of the function args.  For lucid/ARM style, we
4265    account for this difference by discarding any previously seen types when
4266    we see the 'F' character, and subtracting one from the type number
4267    reference.
4268 
4269  */
4270 
4271 static int
demangle_args(struct work_stuff * work,const char ** mangled,string * declp)4272 demangle_args (struct work_stuff *work, const char **mangled,
4273                string *declp)
4274 {
4275   string arg;
4276   int need_comma = 0;
4277   int r;
4278   int t;
4279   const char *tem;
4280   char temptype;
4281 
4282   if (PRINT_ARG_TYPES)
4283     {
4284       string_append (declp, "(");
4285       if (**mangled == '\0')
4286 	{
4287 	  string_append (declp, "void");
4288 	}
4289     }
4290 
4291   while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4292 	 || work->nrepeats > 0)
4293     {
4294       if ((**mangled == 'N') || (**mangled == 'T'))
4295 	{
4296 	  temptype = *(*mangled)++;
4297 
4298 	  if (temptype == 'N')
4299 	    {
4300 	      if (!get_count (mangled, &r))
4301 		{
4302 		  return (0);
4303 		}
4304 	    }
4305 	  else
4306 	    {
4307 	      r = 1;
4308 	    }
4309           if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
4310             {
4311               /* If we have 10 or more types we might have more than a 1 digit
4312                  index so we'll have to consume the whole count here. This
4313                  will lose if the next thing is a type name preceded by a
4314                  count but it's impossible to demangle that case properly
4315                  anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4316                  Pc, ...)"  or "(..., type12, char *, ...)" */
4317               if ((t = consume_count(mangled)) <= 0)
4318                 {
4319                   return (0);
4320                 }
4321             }
4322           else
4323 	    {
4324 	      if (!get_count (mangled, &t))
4325 	    	{
4326 	          return (0);
4327 	    	}
4328 	    }
4329 	  if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4330 	    {
4331 	      t--;
4332 	    }
4333 	  /* Validate the type index.  Protect against illegal indices from
4334 	     malformed type strings.  */
4335 	  if ((t < 0) || (t >= work -> ntypes))
4336 	    {
4337 	      return (0);
4338 	    }
4339 	  while (work->nrepeats > 0 || --r >= 0)
4340 	    {
4341 	      tem = work -> typevec[t];
4342 	      if (need_comma && PRINT_ARG_TYPES)
4343 		{
4344 		  string_append (declp, ", ");
4345 		}
4346 	      if (!do_arg (work, &tem, &arg))
4347 		{
4348 		  return (0);
4349 		}
4350 	      if (PRINT_ARG_TYPES)
4351 		{
4352 		  string_appends (declp, &arg);
4353 		}
4354 	      string_delete (&arg);
4355 	      need_comma = 1;
4356 	    }
4357 	}
4358       else
4359 	{
4360 	  if (need_comma && PRINT_ARG_TYPES)
4361 	    string_append (declp, ", ");
4362 	  if (!do_arg (work, mangled, &arg))
4363 	    return (0);
4364 	  if (PRINT_ARG_TYPES)
4365 	    string_appends (declp, &arg);
4366 	  string_delete (&arg);
4367 	  need_comma = 1;
4368 	}
4369     }
4370 
4371   if (**mangled == 'e')
4372     {
4373       (*mangled)++;
4374       if (PRINT_ARG_TYPES)
4375 	{
4376 	  if (need_comma)
4377 	    {
4378 	      string_append (declp, ",");
4379 	    }
4380 	  string_append (declp, "...");
4381 	}
4382     }
4383 
4384   if (PRINT_ARG_TYPES)
4385     {
4386       string_append (declp, ")");
4387     }
4388   return (1);
4389 }
4390 
4391 /* Like demangle_args, but for demangling the argument lists of function
4392    and method pointers or references, not top-level declarations.  */
4393 
4394 static int
demangle_nested_args(struct work_stuff * work,const char ** mangled,string * declp)4395 demangle_nested_args (struct work_stuff *work, const char **mangled,
4396                       string *declp)
4397 {
4398   string* saved_previous_argument;
4399   int result;
4400   int saved_nrepeats;
4401 
4402   /* The G++ name-mangling algorithm does not remember types on nested
4403      argument lists, unless -fsquangling is used, and in that case the
4404      type vector updated by remember_type is not used.  So, we turn
4405      off remembering of types here.  */
4406   ++work->forgetting_types;
4407 
4408   /* For the repeat codes used with -fsquangling, we must keep track of
4409      the last argument.  */
4410   saved_previous_argument = work->previous_argument;
4411   saved_nrepeats = work->nrepeats;
4412   work->previous_argument = 0;
4413   work->nrepeats = 0;
4414 
4415   /* Actually demangle the arguments.  */
4416   result = demangle_args (work, mangled, declp);
4417 
4418   /* Restore the previous_argument field.  */
4419   if (work->previous_argument)
4420     {
4421       string_delete (work->previous_argument);
4422       free ((char *) work->previous_argument);
4423     }
4424   work->previous_argument = saved_previous_argument;
4425   --work->forgetting_types;
4426   work->nrepeats = saved_nrepeats;
4427 
4428   return result;
4429 }
4430 
4431 static void
demangle_function_name(struct work_stuff * work,const char ** mangled,string * declp,const char * scan)4432 demangle_function_name (struct work_stuff *work, const char **mangled,
4433                         string *declp, const char *scan)
4434 {
4435   size_t i;
4436   string type;
4437   const char *tem;
4438 
4439   string_appendn (declp, (*mangled), scan - (*mangled));
4440   string_need (declp, 1);
4441   *(declp -> p) = '\0';
4442 
4443   /* Consume the function name, including the "__" separating the name
4444      from the signature.  We are guaranteed that SCAN points to the
4445      separator.  */
4446 
4447   (*mangled) = scan + 2;
4448   /* We may be looking at an instantiation of a template function:
4449      foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4450      following _F marks the start of the function arguments.  Handle
4451      the template arguments first. */
4452 
4453   if (HP_DEMANGLING && (**mangled == 'X'))
4454     {
4455       demangle_arm_hp_template (work, mangled, 0, declp);
4456       /* This leaves MANGLED pointing to the 'F' marking func args */
4457     }
4458 
4459   if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4460     {
4461 
4462       /* See if we have an ARM style constructor or destructor operator.
4463 	 If so, then just record it, clear the decl, and return.
4464 	 We can't build the actual constructor/destructor decl until later,
4465 	 when we recover the class name from the signature.  */
4466 
4467       if (strcmp (declp -> b, "__ct") == 0)
4468 	{
4469 	  work -> constructor += 1;
4470 	  string_clear (declp);
4471 	  return;
4472 	}
4473       else if (strcmp (declp -> b, "__dt") == 0)
4474 	{
4475 	  work -> destructor += 1;
4476 	  string_clear (declp);
4477 	  return;
4478 	}
4479     }
4480 
4481   if (declp->p - declp->b >= 3
4482       && declp->b[0] == 'o'
4483       && declp->b[1] == 'p'
4484       && strchr (cplus_markers, declp->b[2]) != NULL)
4485     {
4486       /* see if it's an assignment expression */
4487       if (declp->p - declp->b >= 10 /* op$assign_ */
4488 	  && memcmp (declp->b + 3, "assign_", 7) == 0)
4489 	{
4490 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
4491 	    {
4492 	      int len = declp->p - declp->b - 10;
4493 	      if ((int) strlen (optable[i].in) == len
4494 		  && memcmp (optable[i].in, declp->b + 10, len) == 0)
4495 		{
4496 		  string_clear (declp);
4497 		  string_append (declp, "operator");
4498 		  string_append (declp, optable[i].out);
4499 		  string_append (declp, "=");
4500 		  break;
4501 		}
4502 	    }
4503 	}
4504       else
4505 	{
4506 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
4507 	    {
4508 	      int len = declp->p - declp->b - 3;
4509 	      if ((int) strlen (optable[i].in) == len
4510 		  && memcmp (optable[i].in, declp->b + 3, len) == 0)
4511 		{
4512 		  string_clear (declp);
4513 		  string_append (declp, "operator");
4514 		  string_append (declp, optable[i].out);
4515 		  break;
4516 		}
4517 	    }
4518 	}
4519     }
4520   else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4521 	   && strchr (cplus_markers, declp->b[4]) != NULL)
4522     {
4523       /* type conversion operator */
4524       tem = declp->b + 5;
4525       if (do_type (work, &tem, &type))
4526 	{
4527 	  string_clear (declp);
4528 	  string_append (declp, "operator ");
4529 	  string_appends (declp, &type);
4530 	  string_delete (&type);
4531 	}
4532     }
4533   else if (declp->b[0] == '_' && declp->b[1] == '_'
4534 	   && declp->b[2] == 'o' && declp->b[3] == 'p')
4535     {
4536       /* ANSI.  */
4537       /* type conversion operator.  */
4538       tem = declp->b + 4;
4539       if (do_type (work, &tem, &type))
4540 	{
4541 	  string_clear (declp);
4542 	  string_append (declp, "operator ");
4543 	  string_appends (declp, &type);
4544 	  string_delete (&type);
4545 	}
4546     }
4547   else if (declp->b[0] == '_' && declp->b[1] == '_'
4548 	   && ISLOWER((unsigned char)declp->b[2])
4549 	   && ISLOWER((unsigned char)declp->b[3]))
4550     {
4551       if (declp->b[4] == '\0')
4552 	{
4553 	  /* Operator.  */
4554 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
4555 	    {
4556 	      if (strlen (optable[i].in) == 2
4557 		  && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4558 		{
4559 		  string_clear (declp);
4560 		  string_append (declp, "operator");
4561 		  string_append (declp, optable[i].out);
4562 		  break;
4563 		}
4564 	    }
4565 	}
4566       else
4567 	{
4568 	  if (declp->b[2] == 'a' && declp->b[5] == '\0')
4569 	    {
4570 	      /* Assignment.  */
4571 	      for (i = 0; i < ARRAY_SIZE (optable); i++)
4572 		{
4573 		  if (strlen (optable[i].in) == 3
4574 		      && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4575 		    {
4576 		      string_clear (declp);
4577 		      string_append (declp, "operator");
4578 		      string_append (declp, optable[i].out);
4579 		      break;
4580 		    }
4581 		}
4582 	    }
4583 	}
4584     }
4585 }
4586 
4587 /* a mini string-handling package */
4588 
4589 static void
string_need(string * s,int n)4590 string_need (string *s, int n)
4591 {
4592   int tem;
4593 
4594   if (s->b == NULL)
4595     {
4596       if (n < 32)
4597 	{
4598 	  n = 32;
4599 	}
4600       s->p = s->b = XNEWVEC (char, n);
4601       s->e = s->b + n;
4602     }
4603   else if (s->e - s->p < n)
4604     {
4605       tem = s->p - s->b;
4606       n += tem;
4607       n *= 2;
4608       s->b = XRESIZEVEC (char, s->b, n);
4609       s->p = s->b + tem;
4610       s->e = s->b + n;
4611     }
4612 }
4613 
4614 static void
string_delete(string * s)4615 string_delete (string *s)
4616 {
4617   if (s->b != NULL)
4618     {
4619       free (s->b);
4620       s->b = s->e = s->p = NULL;
4621     }
4622 }
4623 
4624 static void
string_init(string * s)4625 string_init (string *s)
4626 {
4627   s->b = s->p = s->e = NULL;
4628 }
4629 
4630 static void
string_clear(string * s)4631 string_clear (string *s)
4632 {
4633   s->p = s->b;
4634 }
4635 
4636 #if 0
4637 
4638 static int
4639 string_empty (string *s)
4640 {
4641   return (s->b == s->p);
4642 }
4643 
4644 #endif
4645 
4646 static void
string_append(string * p,const char * s)4647 string_append (string *p, const char *s)
4648 {
4649   int n;
4650   if (s == NULL || *s == '\0')
4651     return;
4652   n = strlen (s);
4653   string_need (p, n);
4654   memcpy (p->p, s, n);
4655   p->p += n;
4656 }
4657 
4658 static void
string_appends(string * p,string * s)4659 string_appends (string *p, string *s)
4660 {
4661   int n;
4662 
4663   if (s->b != s->p)
4664     {
4665       n = s->p - s->b;
4666       string_need (p, n);
4667       memcpy (p->p, s->b, n);
4668       p->p += n;
4669     }
4670 }
4671 
4672 static void
string_appendn(string * p,const char * s,int n)4673 string_appendn (string *p, const char *s, int n)
4674 {
4675   if (n != 0)
4676     {
4677       string_need (p, n);
4678       memcpy (p->p, s, n);
4679       p->p += n;
4680     }
4681 }
4682 
4683 static void
string_prepend(string * p,const char * s)4684 string_prepend (string *p, const char *s)
4685 {
4686   if (s != NULL && *s != '\0')
4687     {
4688       string_prependn (p, s, strlen (s));
4689     }
4690 }
4691 
4692 static void
string_prepends(string * p,string * s)4693 string_prepends (string *p, string *s)
4694 {
4695   if (s->b != s->p)
4696     {
4697       string_prependn (p, s->b, s->p - s->b);
4698     }
4699 }
4700 
4701 static void
string_prependn(string * p,const char * s,int n)4702 string_prependn (string *p, const char *s, int n)
4703 {
4704   char *q;
4705 
4706   if (n != 0)
4707     {
4708       string_need (p, n);
4709       for (q = p->p - 1; q >= p->b; q--)
4710 	{
4711 	  q[n] = q[0];
4712 	}
4713       memcpy (p->b, s, n);
4714       p->p += n;
4715     }
4716 }
4717 
4718 static void
string_append_template_idx(string * s,int idx)4719 string_append_template_idx (string *s, int idx)
4720 {
4721   char buf[INTBUF_SIZE + 1 /* 'T' */];
4722   snprintf(buf, INTBUF_SIZE + 1, "T%d", idx);
4723   string_append (s, buf);
4724 }
4725