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