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