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