xref: /openbsd-src/gnu/lib/libiberty/src/cplus-dem.c (revision daf88648c0e349d5c02e1504293082072c981640)
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      strlcpy (demangled, mangled, demangled_size);
1067   else
1068     snprintf (demangled, demangled_size, "<%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 initializes 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 		string_delete (&s);
1442 	      }
1443 	    oldmangled = NULL;
1444 	    expect_func = 1;
1445 	  }
1446 	  break;
1447 
1448 	case 'F':
1449 	  /* Function */
1450 	  /* ARM/HP style demangling includes a specific 'F' character after
1451 	     the class name.  For GNU style, it is just implied.  So we can
1452 	     safely just consume any 'F' at this point and be compatible
1453 	     with either style.  */
1454 
1455 	  oldmangled = NULL;
1456 	  func_done = 1;
1457 	  (*mangled)++;
1458 
1459 	  /* For lucid/ARM/HP style we have to forget any types we might
1460 	     have remembered up to this point, since they were not argument
1461 	     types.  GNU style considers all types seen as available for
1462 	     back references.  See comment in demangle_args() */
1463 
1464 	  if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1465 	    {
1466 	      forget_types (work);
1467 	    }
1468 	  success = demangle_args (work, mangled, declp);
1469 	  /* After picking off the function args, we expect to either
1470 	     find the function return type (preceded by an '_') or the
1471 	     end of the string. */
1472 	  if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1473 	    {
1474 	      ++(*mangled);
1475               /* At this level, we do not care about the return type. */
1476               success = do_type (work, mangled, &tname);
1477               string_delete (&tname);
1478             }
1479 
1480 	  break;
1481 
1482 	case 't':
1483 	  /* G++ Template */
1484 	  string_init(&trawname);
1485 	  string_init(&tname);
1486 	  if (oldmangled == NULL)
1487 	    {
1488 	      oldmangled = *mangled;
1489 	    }
1490 	  success = demangle_template (work, mangled, &tname,
1491 				       &trawname, 1, 1);
1492 	  if (success)
1493 	    {
1494 	      remember_type (work, oldmangled, *mangled - oldmangled);
1495 	    }
1496 	  string_append (&tname, SCOPE_STRING (work));
1497 
1498 	  string_prepends(declp, &tname);
1499 	  if (work -> destructor & 1)
1500 	    {
1501 	      string_prepend (&trawname, "~");
1502 	      string_appends (declp, &trawname);
1503 	      work->destructor -= 1;
1504 	    }
1505 	  if ((work->constructor & 1) || (work->destructor & 1))
1506 	    {
1507 	      string_appends (declp, &trawname);
1508 	      work->constructor -= 1;
1509 	    }
1510 	  string_delete(&trawname);
1511 	  string_delete(&tname);
1512 	  oldmangled = NULL;
1513 	  expect_func = 1;
1514 	  break;
1515 
1516 	case '_':
1517 	  if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
1518 	    {
1519 	      /* Read the return type. */
1520 	      string 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       if (**mangled == '_')
1801         {
1802 	  if (mangled[0][1] == 'm')
1803 	    {
1804 	      /* Since consume_count_with_underscores does not handle the
1805 		 `m'-prefix we must do it here, using consume_count and
1806 		 adjusting underscores: we have to consume the underscore
1807 		 matching the prepended one.  */
1808 	      multidigit_without_leading_underscore = 1;
1809 	      string_appendn (s, "-", 1);
1810 	      (*mangled) += 2;
1811 	    }
1812 	  else
1813 	    {
1814 	      /* Do not consume a following underscore;
1815 	         consume_count_with_underscores will consume what
1816 	         should be consumed.  */
1817 	      leave_following_underscore = 1;
1818 	    }
1819 	}
1820       else
1821 	{
1822 	  /* Negative numbers are indicated with a leading `m'.  */
1823 	  if (**mangled == 'm')
1824 	  {
1825 	    string_appendn (s, "-", 1);
1826 	    (*mangled)++;
1827 	  }
1828 	  /* Since consume_count_with_underscores does not handle
1829 	     multi-digit numbers that do not start with an underscore,
1830 	     and this number can be an integer template parameter,
1831 	     we have to call consume_count. */
1832 	  multidigit_without_leading_underscore = 1;
1833 	  /* These multi-digit numbers never end on an underscore,
1834 	     so if there is one then don't eat it. */
1835 	  leave_following_underscore = 1;
1836 	}
1837 
1838       /* We must call consume_count if we expect to remove a trailing
1839 	 underscore, since consume_count_with_underscores expects
1840 	 the leading underscore (that we consumed) if it is to handle
1841 	 multi-digit numbers.  */
1842       if (multidigit_without_leading_underscore)
1843 	value = consume_count (mangled);
1844       else
1845 	value = consume_count_with_underscores (mangled);
1846 
1847       if (value != -1)
1848 	{
1849 	  char buf[INTBUF_SIZE];
1850 	  snprintf (buf, sizeof buf, "%d", value);
1851 	  string_append (s, buf);
1852 
1853 	  /* Numbers not otherwise delimited, might have an underscore
1854 	     appended as a delimeter, which we should skip.
1855 
1856 	     ??? This used to always remove a following underscore, which
1857 	     is wrong.  If other (arbitrary) cases are followed by an
1858 	     underscore, we need to do something more radical.  */
1859 
1860 	  if ((value > 9 || multidigit_without_leading_underscore)
1861 	      && ! leave_following_underscore
1862 	      && **mangled == '_')
1863 	    (*mangled)++;
1864 
1865 	  /* All is well.  */
1866 	  success = 1;
1867 	}
1868       }
1869 
1870   return success;
1871 }
1872 
1873 /* Demangle the real value in MANGLED.  */
1874 
1875 static int
1876 demangle_real_value (work, mangled, s)
1877      struct work_stuff *work;
1878      const char **mangled;
1879      string* s;
1880 {
1881   if (**mangled == 'E')
1882     return demangle_expression (work, mangled, s, tk_real);
1883 
1884   if (**mangled == 'm')
1885     {
1886       string_appendn (s, "-", 1);
1887       (*mangled)++;
1888     }
1889   while (ISDIGIT ((unsigned char)**mangled))
1890     {
1891       string_appendn (s, *mangled, 1);
1892       (*mangled)++;
1893     }
1894   if (**mangled == '.') /* fraction */
1895     {
1896       string_appendn (s, ".", 1);
1897       (*mangled)++;
1898       while (ISDIGIT ((unsigned char)**mangled))
1899 	{
1900 	  string_appendn (s, *mangled, 1);
1901 	  (*mangled)++;
1902 	}
1903     }
1904   if (**mangled == 'e') /* exponent */
1905     {
1906       string_appendn (s, "e", 1);
1907       (*mangled)++;
1908       while (ISDIGIT ((unsigned char)**mangled))
1909 	{
1910 	  string_appendn (s, *mangled, 1);
1911 	  (*mangled)++;
1912 	}
1913     }
1914 
1915   return 1;
1916 }
1917 
1918 static int
1919 demangle_template_value_parm (work, mangled, s, tk)
1920      struct work_stuff *work;
1921      const char **mangled;
1922      string* s;
1923      type_kind_t tk;
1924 {
1925   int success = 1;
1926 
1927   if (**mangled == 'Y')
1928     {
1929       /* The next argument is a template parameter. */
1930       int idx;
1931 
1932       (*mangled)++;
1933       idx = consume_count_with_underscores (mangled);
1934       if (idx == -1
1935 	  || (work->tmpl_argvec && idx >= work->ntmpl_args)
1936 	  || consume_count_with_underscores (mangled) == -1)
1937 	return -1;
1938       if (work->tmpl_argvec)
1939 	string_append (s, work->tmpl_argvec[idx]);
1940       else
1941 	string_append_template_idx (s, idx);
1942     }
1943   else if (tk == tk_integral)
1944     success = demangle_integral_value (work, mangled, s);
1945   else if (tk == tk_char)
1946     {
1947       char tmp[2];
1948       int val;
1949       if (**mangled == 'm')
1950 	{
1951 	  string_appendn (s, "-", 1);
1952 	  (*mangled)++;
1953 	}
1954       string_appendn (s, "'", 1);
1955       val = consume_count(mangled);
1956       if (val <= 0)
1957 	success = 0;
1958       else
1959 	{
1960 	  tmp[0] = (char)val;
1961 	  tmp[1] = '\0';
1962 	  string_appendn (s, &tmp[0], 1);
1963 	  string_appendn (s, "'", 1);
1964 	}
1965     }
1966   else if (tk == tk_bool)
1967     {
1968       int val = consume_count (mangled);
1969       if (val == 0)
1970 	string_appendn (s, "false", 5);
1971       else if (val == 1)
1972 	string_appendn (s, "true", 4);
1973       else
1974 	success = 0;
1975     }
1976   else if (tk == tk_real)
1977     success = demangle_real_value (work, mangled, s);
1978   else if (tk == tk_pointer || tk == tk_reference)
1979     {
1980       if (**mangled == 'Q')
1981 	success = demangle_qualified (work, mangled, s,
1982 				      /*isfuncname=*/0,
1983 				      /*append=*/1);
1984       else
1985 	{
1986 	  int symbol_len  = consume_count (mangled);
1987 	  if (symbol_len == -1)
1988 	    return -1;
1989 	  if (symbol_len == 0)
1990 	    string_appendn (s, "0", 1);
1991 	  else
1992 	    {
1993 	      char *p = xmalloc (symbol_len + 1), *q;
1994 	      strncpy (p, *mangled, symbol_len);
1995 	      p [symbol_len] = '\0';
1996 	      /* We use cplus_demangle here, rather than
1997 		 internal_cplus_demangle, because the name of the entity
1998 		 mangled here does not make use of any of the squangling
1999 		 or type-code information we have built up thus far; it is
2000 		 mangled independently.  */
2001 	      q = cplus_demangle (p, work->options);
2002 	      if (tk == tk_pointer)
2003 		string_appendn (s, "&", 1);
2004 	      /* FIXME: Pointer-to-member constants should get a
2005 		 qualifying class name here.  */
2006 	      if (q)
2007 		{
2008 		  string_append (s, q);
2009 		  free (q);
2010 		}
2011 	      else
2012 		string_append (s, p);
2013 	      free (p);
2014 	    }
2015 	  *mangled += symbol_len;
2016 	}
2017     }
2018 
2019   return success;
2020 }
2021 
2022 /* Demangle the template name in MANGLED.  The full name of the
2023    template (e.g., S<int>) is placed in TNAME.  The name without the
2024    template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
2025    non-NULL.  If IS_TYPE is nonzero, this template is a type template,
2026    not a function template.  If both IS_TYPE and REMEMBER are nonzero,
2027    the template is remembered in the list of back-referenceable
2028    types.  */
2029 
2030 static int
2031 demangle_template (work, mangled, tname, trawname, is_type, remember)
2032      struct work_stuff *work;
2033      const char **mangled;
2034      string *tname;
2035      string *trawname;
2036      int is_type;
2037      int remember;
2038 {
2039   int i;
2040   int r;
2041   int need_comma = 0;
2042   int success = 0;
2043   const char *start;
2044   int is_java_array = 0;
2045   string temp;
2046   int bindex = 0;
2047 
2048   (*mangled)++;
2049   if (is_type)
2050     {
2051       if (remember)
2052 	bindex = register_Btype (work);
2053       start = *mangled;
2054       /* get template name */
2055       if (**mangled == 'z')
2056 	{
2057 	  int idx;
2058 	  (*mangled)++;
2059 	  (*mangled)++;
2060 
2061 	  idx = consume_count_with_underscores (mangled);
2062 	  if (idx == -1
2063 	      || (work->tmpl_argvec && idx >= work->ntmpl_args)
2064 	      || consume_count_with_underscores (mangled) == -1)
2065 	    return (0);
2066 
2067 	  if (work->tmpl_argvec)
2068 	    {
2069 	      string_append (tname, work->tmpl_argvec[idx]);
2070 	      if (trawname)
2071 		string_append (trawname, work->tmpl_argvec[idx]);
2072 	    }
2073 	  else
2074 	    {
2075 	      string_append_template_idx (tname, idx);
2076 	      if (trawname)
2077 		string_append_template_idx (trawname, idx);
2078 	    }
2079 	}
2080       else
2081 	{
2082 	  if ((r = consume_count (mangled)) <= 0
2083 	      || (int) strlen (*mangled) < r)
2084 	    {
2085 	      return (0);
2086 	    }
2087 	  is_java_array = (work -> options & DMGL_JAVA)
2088 	    && strncmp (*mangled, "JArray1Z", 8) == 0;
2089 	  if (! is_java_array)
2090 	    {
2091 	      string_appendn (tname, *mangled, r);
2092 	    }
2093 	  if (trawname)
2094 	    string_appendn (trawname, *mangled, r);
2095 	  *mangled += r;
2096 	}
2097     }
2098   if (!is_java_array)
2099     string_append (tname, "<");
2100   /* get size of template parameter list */
2101   if (!get_count (mangled, &r))
2102     {
2103       return (0);
2104     }
2105   if (!is_type)
2106     {
2107       /* Create an array for saving the template argument values. */
2108       work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
2109       work->ntmpl_args = r;
2110       for (i = 0; i < r; i++)
2111 	work->tmpl_argvec[i] = 0;
2112     }
2113   for (i = 0; i < r; i++)
2114     {
2115       if (need_comma)
2116 	{
2117 	  string_append (tname, ", ");
2118 	}
2119       /* Z for type parameters */
2120       if (**mangled == 'Z')
2121 	{
2122 	  (*mangled)++;
2123 	  /* temp is initialized in do_type */
2124 	  success = do_type (work, mangled, &temp);
2125 	  if (success)
2126 	    {
2127 	      string_appends (tname, &temp);
2128 
2129 	      if (!is_type)
2130 		{
2131 		  /* Save the template argument. */
2132 		  int len = temp.p - temp.b;
2133 		  work->tmpl_argvec[i] = xmalloc (len + 1);
2134 		  memcpy (work->tmpl_argvec[i], temp.b, len);
2135 		  work->tmpl_argvec[i][len] = '\0';
2136 		}
2137 	    }
2138 	  string_delete(&temp);
2139 	  if (!success)
2140 	    {
2141 	      break;
2142 	    }
2143 	}
2144       /* z for template parameters */
2145       else if (**mangled == 'z')
2146 	{
2147 	  int r2;
2148 	  (*mangled)++;
2149 	  success = demangle_template_template_parm (work, mangled, tname);
2150 
2151 	  if (success
2152 	      && (r2 = consume_count (mangled)) > 0
2153 	      && (int) strlen (*mangled) >= r2)
2154 	    {
2155 	      string_append (tname, " ");
2156 	      string_appendn (tname, *mangled, r2);
2157 	      if (!is_type)
2158 		{
2159 		  /* Save the template argument. */
2160 		  int len = r2;
2161 		  work->tmpl_argvec[i] = xmalloc (len + 1);
2162 		  memcpy (work->tmpl_argvec[i], *mangled, len);
2163 		  work->tmpl_argvec[i][len] = '\0';
2164 		}
2165 	      *mangled += r2;
2166 	    }
2167 	  if (!success)
2168 	    {
2169 	      break;
2170 	    }
2171 	}
2172       else
2173 	{
2174 	  string  param;
2175 	  string* s;
2176 
2177 	  /* otherwise, value parameter */
2178 
2179 	  /* temp is initialized in do_type */
2180 	  success = do_type (work, mangled, &temp);
2181 	  string_delete(&temp);
2182 	  if (!success)
2183 	    break;
2184 
2185 	  if (!is_type)
2186 	    {
2187 	      s = &param;
2188 	      string_init (s);
2189 	    }
2190 	  else
2191 	    s = tname;
2192 
2193 	  success = demangle_template_value_parm (work, mangled, s,
2194 						  (type_kind_t) success);
2195 
2196 	  if (!success)
2197 	    {
2198 	      if (!is_type)
2199 		string_delete (s);
2200 	      success = 0;
2201 	      break;
2202 	    }
2203 
2204 	  if (!is_type)
2205 	    {
2206 	      int len = s->p - s->b;
2207 	      work->tmpl_argvec[i] = xmalloc (len + 1);
2208 	      memcpy (work->tmpl_argvec[i], s->b, len);
2209 	      work->tmpl_argvec[i][len] = '\0';
2210 
2211 	      string_appends (tname, s);
2212 	      string_delete (s);
2213 	    }
2214 	}
2215       need_comma = 1;
2216     }
2217   if (is_java_array)
2218     {
2219       string_append (tname, "[]");
2220     }
2221   else
2222     {
2223       if (tname->p[-1] == '>')
2224 	string_append (tname, " ");
2225       string_append (tname, ">");
2226     }
2227 
2228   if (is_type && remember)
2229     remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
2230 
2231   /*
2232     if (work -> static_type)
2233     {
2234     string_append (declp, *mangled + 1);
2235     *mangled += strlen (*mangled);
2236     success = 1;
2237     }
2238     else
2239     {
2240     success = demangle_args (work, mangled, declp);
2241     }
2242     }
2243     */
2244   return (success);
2245 }
2246 
2247 static int
2248 arm_pt (work, mangled, n, anchor, args)
2249      struct work_stuff *work;
2250      const char *mangled;
2251      int n;
2252      const char **anchor, **args;
2253 {
2254   /* Check if ARM template with "__pt__" in it ("parameterized type") */
2255   /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2256   if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__")))
2257     {
2258       int len;
2259       *args = *anchor + 6;
2260       len = consume_count (args);
2261       if (len == -1)
2262 	return 0;
2263       if (*args + len == mangled + n && **args == '_')
2264 	{
2265 	  ++*args;
2266 	  return 1;
2267 	}
2268     }
2269   if (AUTO_DEMANGLING || EDG_DEMANGLING)
2270     {
2271       if ((*anchor = strstr (mangled, "__tm__"))
2272           || (*anchor = strstr (mangled, "__ps__"))
2273           || (*anchor = strstr (mangled, "__pt__")))
2274         {
2275           int len;
2276           *args = *anchor + 6;
2277           len = consume_count (args);
2278 	  if (len == -1)
2279 	    return 0;
2280           if (*args + len == mangled + n && **args == '_')
2281             {
2282               ++*args;
2283               return 1;
2284             }
2285         }
2286       else if ((*anchor = strstr (mangled, "__S")))
2287         {
2288  	  int len;
2289  	  *args = *anchor + 3;
2290  	  len = consume_count (args);
2291 	  if (len == -1)
2292 	    return 0;
2293  	  if (*args + len == mangled + n && **args == '_')
2294             {
2295               ++*args;
2296  	      return 1;
2297             }
2298         }
2299     }
2300 
2301   return 0;
2302 }
2303 
2304 static void
2305 demangle_arm_hp_template (work, mangled, n, declp)
2306      struct work_stuff *work;
2307      const char **mangled;
2308      int n;
2309      string *declp;
2310 {
2311   const char *p;
2312   const char *args;
2313   const char *e = *mangled + n;
2314   string arg;
2315 
2316   /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2317      template args */
2318   if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
2319     {
2320       char *start_spec_args = NULL;
2321 
2322       /* First check for and omit template specialization pseudo-arguments,
2323          such as in "Spec<#1,#1.*>" */
2324       start_spec_args = strchr (*mangled, '<');
2325       if (start_spec_args && (start_spec_args - *mangled < n))
2326         string_appendn (declp, *mangled, start_spec_args - *mangled);
2327       else
2328         string_appendn (declp, *mangled, n);
2329       (*mangled) += n + 1;
2330       string_init (&arg);
2331       if (work->temp_start == -1) /* non-recursive call */
2332         work->temp_start = declp->p - declp->b;
2333       string_append (declp, "<");
2334       while (1)
2335         {
2336           string_delete (&arg);
2337           switch (**mangled)
2338             {
2339               case 'T':
2340                 /* 'T' signals a type parameter */
2341                 (*mangled)++;
2342                 if (!do_type (work, mangled, &arg))
2343                   goto hpacc_template_args_done;
2344                 break;
2345 
2346               case 'U':
2347               case 'S':
2348                 /* 'U' or 'S' signals an integral value */
2349                 if (!do_hpacc_template_const_value (work, mangled, &arg))
2350                   goto hpacc_template_args_done;
2351                 break;
2352 
2353               case 'A':
2354                 /* 'A' signals a named constant expression (literal) */
2355                 if (!do_hpacc_template_literal (work, mangled, &arg))
2356                   goto hpacc_template_args_done;
2357                 break;
2358 
2359               default:
2360                 /* Today, 1997-09-03, we have only the above types
2361                    of template parameters */
2362                 /* FIXME: maybe this should fail and return null */
2363                 goto hpacc_template_args_done;
2364             }
2365           string_appends (declp, &arg);
2366          /* Check if we're at the end of template args.
2367              0 if at end of static member of template class,
2368              _ if done with template args for a function */
2369           if ((**mangled == '\000') || (**mangled == '_'))
2370             break;
2371           else
2372             string_append (declp, ",");
2373         }
2374     hpacc_template_args_done:
2375       string_append (declp, ">");
2376       string_delete (&arg);
2377       if (**mangled == '_')
2378         (*mangled)++;
2379       return;
2380     }
2381   /* ARM template? (Also handles HP cfront extensions) */
2382   else if (arm_pt (work, *mangled, n, &p, &args))
2383     {
2384       string type_str;
2385 
2386       string_init (&arg);
2387       string_appendn (declp, *mangled, p - *mangled);
2388       if (work->temp_start == -1)  /* non-recursive call */
2389 	work->temp_start = declp->p - declp->b;
2390       string_append (declp, "<");
2391       /* should do error checking here */
2392       while (args < e) {
2393 	string_delete (&arg);
2394 
2395 	/* Check for type or literal here */
2396 	switch (*args)
2397 	  {
2398 	    /* HP cfront extensions to ARM for template args */
2399 	    /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2400 	    /* FIXME: We handle only numeric literals for HP cfront */
2401           case 'X':
2402             /* A typed constant value follows */
2403             args++;
2404             if (!do_type (work, &args, &type_str))
2405 	      goto cfront_template_args_done;
2406             string_append (&arg, "(");
2407             string_appends (&arg, &type_str);
2408             string_delete (&type_str);
2409             string_append (&arg, ")");
2410             if (*args != 'L')
2411               goto cfront_template_args_done;
2412             args++;
2413             /* Now snarf a literal value following 'L' */
2414             if (!snarf_numeric_literal (&args, &arg))
2415 	      goto cfront_template_args_done;
2416             break;
2417 
2418           case 'L':
2419             /* Snarf a literal following 'L' */
2420             args++;
2421             if (!snarf_numeric_literal (&args, &arg))
2422 	      goto cfront_template_args_done;
2423             break;
2424           default:
2425             /* Not handling other HP cfront stuff */
2426             {
2427               const char* old_args = args;
2428               if (!do_type (work, &args, &arg))
2429                 goto cfront_template_args_done;
2430 
2431               /* Fail if we didn't make any progress: prevent infinite loop. */
2432               if (args == old_args)
2433                 return;
2434             }
2435 	  }
2436 	string_appends (declp, &arg);
2437 	string_append (declp, ",");
2438       }
2439     cfront_template_args_done:
2440       string_delete (&arg);
2441       if (args >= e)
2442 	--declp->p; /* remove extra comma */
2443       string_append (declp, ">");
2444     }
2445   else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2446 	   && (*mangled)[9] == 'N'
2447 	   && (*mangled)[8] == (*mangled)[10]
2448 	   && strchr (cplus_markers, (*mangled)[8]))
2449     {
2450       /* A member of the anonymous namespace.  */
2451       string_append (declp, "{anonymous}");
2452     }
2453   else
2454     {
2455       if (work->temp_start == -1) /* non-recursive call only */
2456 	work->temp_start = 0;     /* disable in recursive calls */
2457       string_appendn (declp, *mangled, n);
2458     }
2459   *mangled += n;
2460 }
2461 
2462 /* Extract a class name, possibly a template with arguments, from the
2463    mangled string; qualifiers, local class indicators, etc. have
2464    already been dealt with */
2465 
2466 static int
2467 demangle_class_name (work, mangled, declp)
2468      struct work_stuff *work;
2469      const char **mangled;
2470      string *declp;
2471 {
2472   int n;
2473   int success = 0;
2474 
2475   n = consume_count (mangled);
2476   if (n == -1)
2477     return 0;
2478   if ((int) strlen (*mangled) >= n)
2479     {
2480       demangle_arm_hp_template (work, mangled, n, declp);
2481       success = 1;
2482     }
2483 
2484   return (success);
2485 }
2486 
2487 /*
2488 
2489 LOCAL FUNCTION
2490 
2491 	demangle_class -- demangle a mangled class sequence
2492 
2493 SYNOPSIS
2494 
2495 	static int
2496 	demangle_class (struct work_stuff *work, const char **mangled,
2497 			strint *declp)
2498 
2499 DESCRIPTION
2500 
2501 	DECLP points to the buffer into which demangling is being done.
2502 
2503 	*MANGLED points to the current token to be demangled.  On input,
2504 	it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2505 	On exit, it points to the next token after the mangled class on
2506 	success, or the first unconsumed token on failure.
2507 
2508 	If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2509 	we are demangling a constructor or destructor.  In this case
2510 	we prepend "class::class" or "class::~class" to DECLP.
2511 
2512 	Otherwise, we prepend "class::" to the current DECLP.
2513 
2514 	Reset the constructor/destructor flags once they have been
2515 	"consumed".  This allows demangle_class to be called later during
2516 	the same demangling, to do normal class demangling.
2517 
2518 	Returns 1 if demangling is successful, 0 otherwise.
2519 
2520 */
2521 
2522 static int
2523 demangle_class (work, mangled, declp)
2524      struct work_stuff *work;
2525      const char **mangled;
2526      string *declp;
2527 {
2528   int success = 0;
2529   int btype;
2530   string class_name;
2531   char *save_class_name_end = 0;
2532 
2533   string_init (&class_name);
2534   btype = register_Btype (work);
2535   if (demangle_class_name (work, mangled, &class_name))
2536     {
2537       save_class_name_end = class_name.p;
2538       if ((work->constructor & 1) || (work->destructor & 1))
2539 	{
2540           /* adjust so we don't include template args */
2541           if (work->temp_start && (work->temp_start != -1))
2542             {
2543               class_name.p = class_name.b + work->temp_start;
2544             }
2545 	  string_prepends (declp, &class_name);
2546 	  if (work -> destructor & 1)
2547 	    {
2548 	      string_prepend (declp, "~");
2549               work -> destructor -= 1;
2550 	    }
2551 	  else
2552 	    {
2553 	      work -> constructor -= 1;
2554 	    }
2555 	}
2556       class_name.p = save_class_name_end;
2557       remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2558       remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2559       string_prepend (declp, SCOPE_STRING (work));
2560       string_prepends (declp, &class_name);
2561       success = 1;
2562     }
2563   string_delete (&class_name);
2564   return (success);
2565 }
2566 
2567 
2568 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2569    the rightmost guess.
2570 
2571    Find the correct "__"-sequence where the function name ends and the
2572    signature starts, which is ambiguous with GNU mangling.
2573    Call demangle_signature here, so we can make sure we found the right
2574    one; *mangled will be consumed so caller will not make further calls to
2575    demangle_signature.  */
2576 
2577 static int
2578 iterate_demangle_function (work, mangled, declp, scan)
2579      struct work_stuff *work;
2580      const char **mangled;
2581      string *declp;
2582      const char *scan;
2583 {
2584   const char *mangle_init = *mangled;
2585   int success = 0;
2586   string decl_init;
2587   struct work_stuff work_init;
2588 
2589   if (*(scan + 2) == '\0')
2590     return 0;
2591 
2592   /* Do not iterate for some demangling modes, or if there's only one
2593      "__"-sequence.  This is the normal case.  */
2594   if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING
2595       || strstr (scan + 2, "__") == NULL)
2596     {
2597       demangle_function_name (work, mangled, declp, scan);
2598       return 1;
2599     }
2600 
2601   /* Save state so we can restart if the guess at the correct "__" was
2602      wrong.  */
2603   string_init (&decl_init);
2604   string_appends (&decl_init, declp);
2605   memset (&work_init, 0, sizeof work_init);
2606   work_stuff_copy_to_from (&work_init, work);
2607 
2608   /* Iterate over occurrences of __, allowing names and types to have a
2609      "__" sequence in them.  We must start with the first (not the last)
2610      occurrence, since "__" most often occur between independent mangled
2611      parts, hence starting at the last occurence inside a signature
2612      might get us a "successful" demangling of the signature.  */
2613 
2614   while (scan[2])
2615     {
2616       demangle_function_name (work, mangled, declp, scan);
2617       success = demangle_signature (work, mangled, declp);
2618       if (success)
2619 	break;
2620 
2621       /* Reset demangle state for the next round.  */
2622       *mangled = mangle_init;
2623       string_clear (declp);
2624       string_appends (declp, &decl_init);
2625       work_stuff_copy_to_from (work, &work_init);
2626 
2627       /* Leave this underscore-sequence.  */
2628       scan += 2;
2629 
2630       /* Scan for the next "__" sequence.  */
2631       while (*scan && (scan[0] != '_' || scan[1] != '_'))
2632 	scan++;
2633 
2634       /* Move to last "__" in this sequence.  */
2635       while (*scan && *scan == '_')
2636 	scan++;
2637       scan -= 2;
2638     }
2639 
2640   /* Delete saved state.  */
2641   delete_work_stuff (&work_init);
2642   string_delete (&decl_init);
2643 
2644   return success;
2645 }
2646 
2647 /*
2648 
2649 LOCAL FUNCTION
2650 
2651 	demangle_prefix -- consume the mangled name prefix and find signature
2652 
2653 SYNOPSIS
2654 
2655 	static int
2656 	demangle_prefix (struct work_stuff *work, const char **mangled,
2657 			 string *declp);
2658 
2659 DESCRIPTION
2660 
2661 	Consume and demangle the prefix of the mangled name.
2662 	While processing the function name root, arrange to call
2663 	demangle_signature if the root is ambiguous.
2664 
2665 	DECLP points to the string buffer into which demangled output is
2666 	placed.  On entry, the buffer is empty.  On exit it contains
2667 	the root function name, the demangled operator name, or in some
2668 	special cases either nothing or the completely demangled result.
2669 
2670 	MANGLED points to the current pointer into the mangled name.  As each
2671 	token of the mangled name is consumed, it is updated.  Upon entry
2672 	the current mangled name pointer points to the first character of
2673 	the mangled name.  Upon exit, it should point to the first character
2674 	of the signature if demangling was successful, or to the first
2675 	unconsumed character if demangling of the prefix was unsuccessful.
2676 
2677 	Returns 1 on success, 0 otherwise.
2678  */
2679 
2680 static int
2681 demangle_prefix (work, mangled, declp)
2682      struct work_stuff *work;
2683      const char **mangled;
2684      string *declp;
2685 {
2686   int success = 1;
2687   const char *scan;
2688   int i;
2689 
2690   if (strlen(*mangled) > 6
2691       && (strncmp(*mangled, "_imp__", 6) == 0
2692           || strncmp(*mangled, "__imp_", 6) == 0))
2693     {
2694       /* it's a symbol imported from a PE dynamic library. Check for both
2695          new style prefix _imp__ and legacy __imp_ used by older versions
2696 	 of dlltool. */
2697       (*mangled) += 6;
2698       work->dllimported = 1;
2699     }
2700   else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2701     {
2702       char *marker = strchr (cplus_markers, (*mangled)[8]);
2703       if (marker != NULL && *marker == (*mangled)[10])
2704 	{
2705 	  if ((*mangled)[9] == 'D')
2706 	    {
2707 	      /* it's a GNU global destructor to be executed at program exit */
2708 	      (*mangled) += 11;
2709 	      work->destructor = 2;
2710 	      if (gnu_special (work, mangled, declp))
2711 		return success;
2712 	    }
2713 	  else if ((*mangled)[9] == 'I')
2714 	    {
2715 	      /* it's a GNU global constructor to be executed at program init */
2716 	      (*mangled) += 11;
2717 	      work->constructor = 2;
2718 	      if (gnu_special (work, mangled, declp))
2719 		return success;
2720 	    }
2721 	}
2722     }
2723   else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2724     {
2725       /* it's a ARM global destructor to be executed at program exit */
2726       (*mangled) += 7;
2727       work->destructor = 2;
2728     }
2729   else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2730     {
2731       /* it's a ARM global constructor to be executed at program initial */
2732       (*mangled) += 7;
2733       work->constructor = 2;
2734     }
2735 
2736   /*  This block of code is a reduction in strength time optimization
2737       of:
2738       scan = strstr (*mangled, "__"); */
2739 
2740   {
2741     scan = *mangled;
2742 
2743     do {
2744       scan = strchr (scan, '_');
2745     } while (scan != NULL && *++scan != '_');
2746 
2747     if (scan != NULL) --scan;
2748   }
2749 
2750   if (scan != NULL)
2751     {
2752       /* We found a sequence of two or more '_', ensure that we start at
2753 	 the last pair in the sequence.  */
2754       i = strspn (scan, "_");
2755       if (i > 2)
2756 	{
2757 	  scan += (i - 2);
2758 	}
2759     }
2760 
2761   if (scan == NULL)
2762     {
2763       success = 0;
2764     }
2765   else if (work -> static_type)
2766     {
2767       if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
2768 	{
2769 	  success = 0;
2770 	}
2771     }
2772   else if ((scan == *mangled)
2773 	   && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
2774 	       || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2775     {
2776       /* The ARM says nothing about the mangling of local variables.
2777 	 But cfront mangles local variables by prepending __<nesting_level>
2778 	 to them. As an extension to ARM demangling we handle this case.  */
2779       if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2780 	  && ISDIGIT ((unsigned char)scan[2]))
2781 	{
2782 	  *mangled = scan + 2;
2783 	  consume_count (mangled);
2784 	  string_append (declp, *mangled);
2785 	  *mangled += strlen (*mangled);
2786 	  success = 1;
2787 	}
2788       else
2789 	{
2790 	  /* A GNU style constructor starts with __[0-9Qt].  But cfront uses
2791 	     names like __Q2_3foo3bar for nested type names.  So don't accept
2792 	     this style of constructor for cfront demangling.  A GNU
2793 	     style member-template constructor starts with 'H'. */
2794 	  if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2795 	    work -> constructor += 1;
2796 	  *mangled = scan + 2;
2797 	}
2798     }
2799   else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2800     {
2801       /* Cfront-style parameterized type.  Handled later as a signature. */
2802       success = 1;
2803 
2804       /* ARM template? */
2805       demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2806     }
2807   else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2808                               || (scan[2] == 'p' && scan[3] == 's')
2809                               || (scan[2] == 'p' && scan[3] == 't')))
2810     {
2811       /* EDG-style parameterized type.  Handled later as a signature. */
2812       success = 1;
2813 
2814       /* EDG template? */
2815       demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2816     }
2817   else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
2818 	   && (scan[2] != 't'))
2819     {
2820       /* Mangled name starts with "__".  Skip over any leading '_' characters,
2821 	 then find the next "__" that separates the prefix from the signature.
2822 	 */
2823       if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2824 	  || (arm_special (mangled, declp) == 0))
2825 	{
2826 	  while (*scan == '_')
2827 	    {
2828 	      scan++;
2829 	    }
2830 	  if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2831 	    {
2832 	      /* No separator (I.E. "__not_mangled"), or empty signature
2833 		 (I.E. "__not_mangled_either__") */
2834 	      success = 0;
2835 	    }
2836 	  else
2837 	    return iterate_demangle_function (work, mangled, declp, scan);
2838 	}
2839     }
2840   else if (*(scan + 2) != '\0')
2841     {
2842       /* Mangled name does not start with "__" but does have one somewhere
2843 	 in there with non empty stuff after it.  Looks like a global
2844 	 function name.  Iterate over all "__":s until the right
2845 	 one is found.  */
2846       return iterate_demangle_function (work, mangled, declp, scan);
2847     }
2848   else
2849     {
2850       /* Doesn't look like a mangled name */
2851       success = 0;
2852     }
2853 
2854   if (!success && (work->constructor == 2 || work->destructor == 2))
2855     {
2856       string_append (declp, *mangled);
2857       *mangled += strlen (*mangled);
2858       success = 1;
2859     }
2860   return (success);
2861 }
2862 
2863 /*
2864 
2865 LOCAL FUNCTION
2866 
2867 	gnu_special -- special handling of gnu mangled strings
2868 
2869 SYNOPSIS
2870 
2871 	static int
2872 	gnu_special (struct work_stuff *work, const char **mangled,
2873 		     string *declp);
2874 
2875 
2876 DESCRIPTION
2877 
2878 	Process some special GNU style mangling forms that don't fit
2879 	the normal pattern.  For example:
2880 
2881 		_$_3foo		(destructor for class foo)
2882 		_vt$foo		(foo virtual table)
2883 		_vt$foo$bar	(foo::bar virtual table)
2884 		__vt_foo	(foo virtual table, new style with thunks)
2885 		_3foo$varname	(static data member)
2886 		_Q22rs2tu$vw	(static data member)
2887 		__t6vector1Zii	(constructor with template)
2888 		__thunk_4__$_7ostream (virtual function thunk)
2889  */
2890 
2891 static int
2892 gnu_special (work, mangled, declp)
2893      struct work_stuff *work;
2894      const char **mangled;
2895      string *declp;
2896 {
2897   int n;
2898   int success = 1;
2899   const char *p;
2900 
2901   if ((*mangled)[0] == '_'
2902       && strchr (cplus_markers, (*mangled)[1]) != NULL
2903       && (*mangled)[2] == '_')
2904     {
2905       /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2906       (*mangled) += 3;
2907       work -> destructor += 1;
2908     }
2909   else if ((*mangled)[0] == '_'
2910 	   && (((*mangled)[1] == '_'
2911 		&& (*mangled)[2] == 'v'
2912 		&& (*mangled)[3] == 't'
2913 		&& (*mangled)[4] == '_')
2914 	       || ((*mangled)[1] == 'v'
2915 		   && (*mangled)[2] == 't'
2916 		   && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2917     {
2918       /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2919          and create the decl.  Note that we consume the entire mangled
2920 	 input string, which means that demangle_signature has no work
2921 	 to do.  */
2922       if ((*mangled)[2] == 'v')
2923 	(*mangled) += 5; /* New style, with thunks: "__vt_" */
2924       else
2925 	(*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2926       while (**mangled != '\0')
2927 	{
2928 	  switch (**mangled)
2929 	    {
2930 	    case 'Q':
2931 	    case 'K':
2932 	      success = demangle_qualified (work, mangled, declp, 0, 1);
2933 	      break;
2934 	    case 't':
2935 	      success = demangle_template (work, mangled, declp, 0, 1,
2936 					   1);
2937 	      break;
2938 	    default:
2939 	      if (ISDIGIT((unsigned char)*mangled[0]))
2940 		{
2941 		  n = consume_count(mangled);
2942 		  /* We may be seeing a too-large size, or else a
2943 		     ".<digits>" indicating a static local symbol.  In
2944 		     any case, declare victory and move on; *don't* try
2945 		     to use n to allocate.  */
2946 		  if (n > (int) strlen (*mangled))
2947 		    {
2948 		      success = 1;
2949 		      break;
2950 		    }
2951 		}
2952 	      else
2953 		{
2954 		  n = strcspn (*mangled, cplus_markers);
2955 		}
2956 	      string_appendn (declp, *mangled, n);
2957 	      (*mangled) += n;
2958 	    }
2959 
2960 	  p = strpbrk (*mangled, cplus_markers);
2961 	  if (success && ((p == NULL) || (p == *mangled)))
2962 	    {
2963 	      if (p != NULL)
2964 		{
2965 		  string_append (declp, SCOPE_STRING (work));
2966 		  (*mangled)++;
2967 		}
2968 	    }
2969 	  else
2970 	    {
2971 	      success = 0;
2972 	      break;
2973 	    }
2974 	}
2975       if (success)
2976 	string_append (declp, " virtual table");
2977     }
2978   else if ((*mangled)[0] == '_'
2979 	   && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2980 	   && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2981     {
2982       /* static data member, "_3foo$varname" for example */
2983       (*mangled)++;
2984       switch (**mangled)
2985 	{
2986 	case 'Q':
2987 	case 'K':
2988 	  success = demangle_qualified (work, mangled, declp, 0, 1);
2989 	  break;
2990 	case 't':
2991 	  success = demangle_template (work, mangled, declp, 0, 1, 1);
2992 	  break;
2993 	default:
2994 	  n = consume_count (mangled);
2995 	  if (n < 0 || n > (long) strlen (*mangled))
2996 	    {
2997 	      success = 0;
2998 	      break;
2999 	    }
3000 
3001 	  if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
3002 	      && (*mangled)[9] == 'N'
3003 	      && (*mangled)[8] == (*mangled)[10]
3004 	      && strchr (cplus_markers, (*mangled)[8]))
3005 	    {
3006 	      /* A member of the anonymous namespace.  There's information
3007 		 about what identifier or filename it was keyed to, but
3008 		 it's just there to make the mangled name unique; we just
3009 		 step over it.  */
3010 	      string_append (declp, "{anonymous}");
3011 	      (*mangled) += n;
3012 
3013 	      /* Now p points to the marker before the N, so we need to
3014 		 update it to the first marker after what we consumed.  */
3015 	      p = strpbrk (*mangled, cplus_markers);
3016 	      break;
3017 	    }
3018 
3019 	  string_appendn (declp, *mangled, n);
3020 	  (*mangled) += n;
3021 	}
3022       if (success && (p == *mangled))
3023 	{
3024 	  /* Consumed everything up to the cplus_marker, append the
3025 	     variable name.  */
3026 	  (*mangled)++;
3027 	  string_append (declp, SCOPE_STRING (work));
3028 	  n = strlen (*mangled);
3029 	  string_appendn (declp, *mangled, n);
3030 	  (*mangled) += n;
3031 	}
3032       else
3033 	{
3034 	  success = 0;
3035 	}
3036     }
3037   else if (strncmp (*mangled, "__thunk_", 8) == 0)
3038     {
3039       int delta;
3040 
3041       (*mangled) += 8;
3042       delta = consume_count (mangled);
3043       if (delta == -1)
3044 	success = 0;
3045       else
3046 	{
3047 	  char *method = internal_cplus_demangle (work, ++*mangled);
3048 
3049 	  if (method)
3050 	    {
3051 	      char buf[50];
3052 	      snprintf (buf, sizeof buf,
3053 	      	"virtual function thunk (delta:%d) for ", -delta);
3054 	      string_append (declp, buf);
3055 	      string_append (declp, method);
3056 	      free (method);
3057 	      n = strlen (*mangled);
3058 	      (*mangled) += n;
3059 	    }
3060 	  else
3061 	    {
3062 	      success = 0;
3063 	    }
3064 	}
3065     }
3066   else if (strncmp (*mangled, "__t", 3) == 0
3067 	   && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
3068     {
3069       p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
3070       (*mangled) += 4;
3071       switch (**mangled)
3072 	{
3073 	case 'Q':
3074 	case 'K':
3075 	  success = demangle_qualified (work, mangled, declp, 0, 1);
3076 	  break;
3077 	case 't':
3078 	  success = demangle_template (work, mangled, declp, 0, 1, 1);
3079 	  break;
3080 	default:
3081 	  success = do_type (work, mangled, declp);
3082 	  break;
3083 	}
3084       if (success && **mangled != '\0')
3085 	success = 0;
3086       if (success)
3087 	string_append (declp, p);
3088     }
3089   else
3090     {
3091       success = 0;
3092     }
3093   return (success);
3094 }
3095 
3096 static void
3097 recursively_demangle(work, mangled, result, namelength)
3098      struct work_stuff *work;
3099      const char **mangled;
3100      string *result;
3101      int namelength;
3102 {
3103   char * recurse = (char *)NULL;
3104   char * recurse_dem = (char *)NULL;
3105 
3106   recurse = (char *) xmalloc (namelength + 1);
3107   memcpy (recurse, *mangled, namelength);
3108   recurse[namelength] = '\000';
3109 
3110   recurse_dem = cplus_demangle (recurse, work->options);
3111 
3112   if (recurse_dem)
3113     {
3114       string_append (result, recurse_dem);
3115       free (recurse_dem);
3116     }
3117   else
3118     {
3119       string_appendn (result, *mangled, namelength);
3120     }
3121   free (recurse);
3122   *mangled += namelength;
3123 }
3124 
3125 /*
3126 
3127 LOCAL FUNCTION
3128 
3129 	arm_special -- special handling of ARM/lucid mangled strings
3130 
3131 SYNOPSIS
3132 
3133 	static int
3134 	arm_special (const char **mangled,
3135 		     string *declp);
3136 
3137 
3138 DESCRIPTION
3139 
3140 	Process some special ARM style mangling forms that don't fit
3141 	the normal pattern.  For example:
3142 
3143 		__vtbl__3foo		(foo virtual table)
3144 		__vtbl__3foo__3bar	(bar::foo virtual table)
3145 
3146  */
3147 
3148 static int
3149 arm_special (mangled, declp)
3150      const char **mangled;
3151      string *declp;
3152 {
3153   int n;
3154   int success = 1;
3155   const char *scan;
3156 
3157   if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
3158     {
3159       /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3160          and create the decl.  Note that we consume the entire mangled
3161 	 input string, which means that demangle_signature has no work
3162 	 to do.  */
3163       scan = *mangled + ARM_VTABLE_STRLEN;
3164       while (*scan != '\0')        /* first check it can be demangled */
3165         {
3166           n = consume_count (&scan);
3167           if (n == -1)
3168 	    {
3169 	      return (0);           /* no good */
3170 	    }
3171           scan += n;
3172           if (scan[0] == '_' && scan[1] == '_')
3173 	    {
3174 	      scan += 2;
3175 	    }
3176         }
3177       (*mangled) += ARM_VTABLE_STRLEN;
3178       while (**mangled != '\0')
3179 	{
3180 	  n = consume_count (mangled);
3181           if (n == -1
3182 	      || n > (long) strlen (*mangled))
3183 	    return 0;
3184 	  string_prependn (declp, *mangled, n);
3185 	  (*mangled) += n;
3186 	  if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
3187 	    {
3188 	      string_prepend (declp, "::");
3189 	      (*mangled) += 2;
3190 	    }
3191 	}
3192       string_append (declp, " virtual table");
3193     }
3194   else
3195     {
3196       success = 0;
3197     }
3198   return (success);
3199 }
3200 
3201 /*
3202 
3203 LOCAL FUNCTION
3204 
3205 	demangle_qualified -- demangle 'Q' qualified name strings
3206 
3207 SYNOPSIS
3208 
3209 	static int
3210 	demangle_qualified (struct work_stuff *, const char *mangled,
3211 			    string *result, int isfuncname, int append);
3212 
3213 DESCRIPTION
3214 
3215 	Demangle a qualified name, such as "Q25Outer5Inner" which is
3216 	the mangled form of "Outer::Inner".  The demangled output is
3217 	prepended or appended to the result string according to the
3218 	state of the append flag.
3219 
3220 	If isfuncname is nonzero, then the qualified name we are building
3221 	is going to be used as a member function name, so if it is a
3222 	constructor or destructor function, append an appropriate
3223 	constructor or destructor name.  I.E. for the above example,
3224 	the result for use as a constructor is "Outer::Inner::Inner"
3225 	and the result for use as a destructor is "Outer::Inner::~Inner".
3226 
3227 BUGS
3228 
3229 	Numeric conversion is ASCII dependent (FIXME).
3230 
3231  */
3232 
3233 static int
3234 demangle_qualified (work, mangled, result, isfuncname, append)
3235      struct work_stuff *work;
3236      const char **mangled;
3237      string *result;
3238      int isfuncname;
3239      int append;
3240 {
3241   int qualifiers = 0;
3242   int success = 1;
3243   char num[2];
3244   string temp;
3245   string last_name;
3246   int bindex = register_Btype (work);
3247 
3248   /* We only make use of ISFUNCNAME if the entity is a constructor or
3249      destructor.  */
3250   isfuncname = (isfuncname
3251 		&& ((work->constructor & 1) || (work->destructor & 1)));
3252 
3253   string_init (&temp);
3254   string_init (&last_name);
3255 
3256   if ((*mangled)[0] == 'K')
3257     {
3258     /* Squangling qualified name reuse */
3259       int idx;
3260       (*mangled)++;
3261       idx = consume_count_with_underscores (mangled);
3262       if (idx == -1 || idx >= work -> numk)
3263         success = 0;
3264       else
3265         string_append (&temp, work -> ktypevec[idx]);
3266     }
3267   else
3268     switch ((*mangled)[1])
3269     {
3270     case '_':
3271       /* GNU mangled name with more than 9 classes.  The count is preceded
3272 	 by an underscore (to distinguish it from the <= 9 case) and followed
3273 	 by an underscore.  */
3274       (*mangled)++;
3275       qualifiers = consume_count_with_underscores (mangled);
3276       if (qualifiers == -1)
3277 	success = 0;
3278       break;
3279 
3280     case '1':
3281     case '2':
3282     case '3':
3283     case '4':
3284     case '5':
3285     case '6':
3286     case '7':
3287     case '8':
3288     case '9':
3289       /* The count is in a single digit.  */
3290       num[0] = (*mangled)[1];
3291       num[1] = '\0';
3292       qualifiers = atoi (num);
3293 
3294       /* If there is an underscore after the digit, skip it.  This is
3295 	 said to be for ARM-qualified names, but the ARM makes no
3296 	 mention of such an underscore.  Perhaps cfront uses one.  */
3297       if ((*mangled)[2] == '_')
3298 	{
3299 	  (*mangled)++;
3300 	}
3301       (*mangled) += 2;
3302       break;
3303 
3304     case '0':
3305     default:
3306       success = 0;
3307     }
3308 
3309   if (!success)
3310     return success;
3311 
3312   /* Pick off the names and collect them in the temp buffer in the order
3313      in which they are found, separated by '::'.  */
3314 
3315   while (qualifiers-- > 0)
3316     {
3317       int remember_K = 1;
3318       string_clear (&last_name);
3319 
3320       if (*mangled[0] == '_')
3321 	(*mangled)++;
3322 
3323       if (*mangled[0] == 't')
3324 	{
3325 	  /* Here we always append to TEMP since we will want to use
3326 	     the template name without the template parameters as a
3327 	     constructor or destructor name.  The appropriate
3328 	     (parameter-less) value is returned by demangle_template
3329 	     in LAST_NAME.  We do not remember the template type here,
3330 	     in order to match the G++ mangling algorithm.  */
3331 	  success = demangle_template(work, mangled, &temp,
3332 				      &last_name, 1, 0);
3333 	  if (!success)
3334 	    break;
3335 	}
3336       else if (*mangled[0] == 'K')
3337 	{
3338           int idx;
3339           (*mangled)++;
3340           idx = consume_count_with_underscores (mangled);
3341           if (idx == -1 || idx >= work->numk)
3342             success = 0;
3343           else
3344             string_append (&temp, work->ktypevec[idx]);
3345           remember_K = 0;
3346 
3347 	  if (!success) break;
3348 	}
3349       else
3350 	{
3351 	  if (EDG_DEMANGLING)
3352             {
3353 	      int namelength;
3354  	      /* Now recursively demangle the qualifier
3355  	       * This is necessary to deal with templates in
3356  	       * mangling styles like EDG */
3357 	      namelength = consume_count (mangled);
3358 	      if (namelength == -1)
3359 		{
3360 		  success = 0;
3361 		  break;
3362 		}
3363  	      recursively_demangle(work, mangled, &temp, namelength);
3364             }
3365           else
3366             {
3367               string_delete (&last_name);
3368               success = do_type (work, mangled, &last_name);
3369               if (!success)
3370                 break;
3371               string_appends (&temp, &last_name);
3372             }
3373 	}
3374 
3375       if (remember_K)
3376 	remember_Ktype (work, temp.b, LEN_STRING (&temp));
3377 
3378       if (qualifiers > 0)
3379 	string_append (&temp, SCOPE_STRING (work));
3380     }
3381 
3382   remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
3383 
3384   /* If we are using the result as a function name, we need to append
3385      the appropriate '::' separated constructor or destructor name.
3386      We do this here because this is the most convenient place, where
3387      we already have a pointer to the name and the length of the name.  */
3388 
3389   if (isfuncname)
3390     {
3391       string_append (&temp, SCOPE_STRING (work));
3392       if (work -> destructor & 1)
3393 	string_append (&temp, "~");
3394       string_appends (&temp, &last_name);
3395     }
3396 
3397   /* Now either prepend the temp buffer to the result, or append it,
3398      depending upon the state of the append flag.  */
3399 
3400   if (append)
3401     string_appends (result, &temp);
3402   else
3403     {
3404       if (!STRING_EMPTY (result))
3405 	string_append (&temp, SCOPE_STRING (work));
3406       string_prepends (result, &temp);
3407     }
3408 
3409   string_delete (&last_name);
3410   string_delete (&temp);
3411   return (success);
3412 }
3413 
3414 /*
3415 
3416 LOCAL FUNCTION
3417 
3418 	get_count -- convert an ascii count to integer, consuming tokens
3419 
3420 SYNOPSIS
3421 
3422 	static int
3423 	get_count (const char **type, int *count)
3424 
3425 DESCRIPTION
3426 
3427 	Assume that *type points at a count in a mangled name; set
3428 	*count to its value, and set *type to the next character after
3429 	the count.  There are some weird rules in effect here.
3430 
3431 	If *type does not point at a string of digits, return zero.
3432 
3433 	If *type points at a string of digits followed by an
3434 	underscore, set *count to their value as an integer, advance
3435 	*type to point *after the underscore, and return 1.
3436 
3437 	If *type points at a string of digits not followed by an
3438 	underscore, consume only the first digit.  Set *count to its
3439 	value as an integer, leave *type pointing after that digit,
3440 	and return 1.
3441 
3442         The excuse for this odd behavior: in the ARM and HP demangling
3443         styles, a type can be followed by a repeat count of the form
3444         `Nxy', where:
3445 
3446         `x' is a single digit specifying how many additional copies
3447             of the type to append to the argument list, and
3448 
3449         `y' is one or more digits, specifying the zero-based index of
3450             the first repeated argument in the list.  Yes, as you're
3451             unmangling the name you can figure this out yourself, but
3452             it's there anyway.
3453 
3454         So, for example, in `bar__3fooFPiN51', the first argument is a
3455         pointer to an integer (`Pi'), and then the next five arguments
3456         are the same (`N5'), and the first repeat is the function's
3457         second argument (`1').
3458 */
3459 
3460 static int
3461 get_count (type, count)
3462      const char **type;
3463      int *count;
3464 {
3465   const char *p;
3466   int n;
3467 
3468   if (!ISDIGIT ((unsigned char)**type))
3469     return (0);
3470   else
3471     {
3472       *count = **type - '0';
3473       (*type)++;
3474       if (ISDIGIT ((unsigned char)**type))
3475 	{
3476 	  p = *type;
3477 	  n = *count;
3478 	  do
3479 	    {
3480 	      n *= 10;
3481 	      n += *p - '0';
3482 	      p++;
3483 	    }
3484 	  while (ISDIGIT ((unsigned char)*p));
3485 	  if (*p == '_')
3486 	    {
3487 	      *type = p + 1;
3488 	      *count = n;
3489 	    }
3490 	}
3491     }
3492   return (1);
3493 }
3494 
3495 /* RESULT will be initialised here; it will be freed on failure.  The
3496    value returned is really a type_kind_t.  */
3497 
3498 static int
3499 do_type (work, mangled, result)
3500      struct work_stuff *work;
3501      const char **mangled;
3502      string *result;
3503 {
3504   int n;
3505   int done;
3506   int success;
3507   string decl;
3508   const char *remembered_type;
3509   int type_quals;
3510   type_kind_t tk = tk_none;
3511 
3512   string_init (&decl);
3513   string_init (result);
3514 
3515   done = 0;
3516   success = 1;
3517   while (success && !done)
3518     {
3519       int member;
3520       switch (**mangled)
3521 	{
3522 
3523 	  /* A pointer type */
3524 	case 'P':
3525 	case 'p':
3526 	  (*mangled)++;
3527 	  if (! (work -> options & DMGL_JAVA))
3528 	    string_prepend (&decl, "*");
3529 	  if (tk == tk_none)
3530 	    tk = tk_pointer;
3531 	  break;
3532 
3533 	  /* A reference type */
3534 	case 'R':
3535 	  (*mangled)++;
3536 	  string_prepend (&decl, "&");
3537 	  if (tk == tk_none)
3538 	    tk = tk_reference;
3539 	  break;
3540 
3541 	  /* An array */
3542 	case 'A':
3543 	  {
3544 	    ++(*mangled);
3545 	    if (!STRING_EMPTY (&decl)
3546 		&& (decl.b[0] == '*' || decl.b[0] == '&'))
3547 	      {
3548 		string_prepend (&decl, "(");
3549 		string_append (&decl, ")");
3550 	      }
3551 	    string_append (&decl, "[");
3552 	    if (**mangled != '_')
3553 	      success = demangle_template_value_parm (work, mangled, &decl,
3554 						      tk_integral);
3555 	    if (**mangled == '_')
3556 	      ++(*mangled);
3557 	    string_append (&decl, "]");
3558 	    break;
3559 	  }
3560 
3561 	/* A back reference to a previously seen type */
3562 	case 'T':
3563 	  (*mangled)++;
3564 	  if (!get_count (mangled, &n) || n >= work -> ntypes)
3565 	    {
3566 	      success = 0;
3567 	    }
3568 	  else
3569 	    {
3570 	      remembered_type = work -> typevec[n];
3571 	      mangled = &remembered_type;
3572 	    }
3573 	  break;
3574 
3575 	  /* A function */
3576 	case 'F':
3577 	  (*mangled)++;
3578 	    if (!STRING_EMPTY (&decl)
3579 		&& (decl.b[0] == '*' || decl.b[0] == '&'))
3580 	    {
3581 	      string_prepend (&decl, "(");
3582 	      string_append (&decl, ")");
3583 	    }
3584 	  /* After picking off the function args, we expect to either find the
3585 	     function return type (preceded by an '_') or the end of the
3586 	     string.  */
3587 	  if (!demangle_nested_args (work, mangled, &decl)
3588 	      || (**mangled != '_' && **mangled != '\0'))
3589 	    {
3590 	      success = 0;
3591 	      break;
3592 	    }
3593 	  if (success && (**mangled == '_'))
3594 	    (*mangled)++;
3595 	  break;
3596 
3597 	case 'M':
3598 	case 'O':
3599 	  {
3600 	    type_quals = TYPE_UNQUALIFIED;
3601 
3602 	    member = **mangled == 'M';
3603 	    (*mangled)++;
3604 
3605 	    string_append (&decl, ")");
3606 
3607 	    /* We don't need to prepend `::' for a qualified name;
3608 	       demangle_qualified will do that for us.  */
3609 	    if (**mangled != 'Q')
3610 	      string_prepend (&decl, SCOPE_STRING (work));
3611 
3612 	    if (ISDIGIT ((unsigned char)**mangled))
3613 	      {
3614 		n = consume_count (mangled);
3615 		if (n == -1
3616 		    || (int) strlen (*mangled) < n)
3617 		  {
3618 		    success = 0;
3619 		    break;
3620 		  }
3621 		string_prependn (&decl, *mangled, n);
3622 		*mangled += n;
3623 	      }
3624 	    else if (**mangled == 'X' || **mangled == 'Y')
3625 	      {
3626 		string temp;
3627 		do_type (work, mangled, &temp);
3628 		string_prepends (&decl, &temp);
3629 		string_delete (&temp);
3630 	      }
3631 	    else if (**mangled == 't')
3632 	      {
3633 		string temp;
3634 		string_init (&temp);
3635 		success = demangle_template (work, mangled, &temp,
3636 					     NULL, 1, 1);
3637 		if (success)
3638 		  {
3639 		    string_prependn (&decl, temp.b, temp.p - temp.b);
3640 		    string_delete (&temp);
3641 		  }
3642 		else
3643 		  break;
3644 	      }
3645 	    else if (**mangled == 'Q')
3646 	      {
3647 		success = demangle_qualified (work, mangled, &decl,
3648 					      /*isfuncnam=*/0,
3649 					      /*append=*/0);
3650 		if (!success)
3651 		  break;
3652 	      }
3653 	    else
3654 	      {
3655 		success = 0;
3656 		break;
3657 	      }
3658 
3659 	    string_prepend (&decl, "(");
3660 	    if (member)
3661 	      {
3662 		switch (**mangled)
3663 		  {
3664 		  case 'C':
3665 		  case 'V':
3666 		  case 'u':
3667 		    type_quals |= code_for_qualifier (**mangled);
3668 		    (*mangled)++;
3669 		    break;
3670 
3671 		  default:
3672 		    break;
3673 		  }
3674 
3675 		if (*(*mangled)++ != 'F')
3676 		  {
3677 		    success = 0;
3678 		    break;
3679 		  }
3680 	      }
3681 	    if ((member && !demangle_nested_args (work, mangled, &decl))
3682 		|| **mangled != '_')
3683 	      {
3684 		success = 0;
3685 		break;
3686 	      }
3687 	    (*mangled)++;
3688 	    if (! PRINT_ANSI_QUALIFIERS)
3689 	      {
3690 		break;
3691 	      }
3692 	    if (type_quals != TYPE_UNQUALIFIED)
3693 	      {
3694 		APPEND_BLANK (&decl);
3695 		string_append (&decl, qualifier_string (type_quals));
3696 	      }
3697 	    break;
3698 	  }
3699         case 'G':
3700 	  (*mangled)++;
3701 	  break;
3702 
3703 	case 'C':
3704 	case 'V':
3705 	case 'u':
3706 	  if (PRINT_ANSI_QUALIFIERS)
3707 	    {
3708 	      if (!STRING_EMPTY (&decl))
3709 		string_prepend (&decl, " ");
3710 
3711 	      string_prepend (&decl, demangle_qualifier (**mangled));
3712 	    }
3713 	  (*mangled)++;
3714 	  break;
3715 	  /*
3716 	    }
3717 	    */
3718 
3719 	  /* fall through */
3720 	default:
3721 	  done = 1;
3722 	  break;
3723 	}
3724     }
3725 
3726   if (success) switch (**mangled)
3727     {
3728       /* A qualified name, such as "Outer::Inner".  */
3729     case 'Q':
3730     case 'K':
3731       {
3732         success = demangle_qualified (work, mangled, result, 0, 1);
3733         break;
3734       }
3735 
3736     /* A back reference to a previously seen squangled type */
3737     case 'B':
3738       (*mangled)++;
3739       if (!get_count (mangled, &n) || n >= work -> numb)
3740 	success = 0;
3741       else
3742 	string_append (result, work->btypevec[n]);
3743       break;
3744 
3745     case 'X':
3746     case 'Y':
3747       /* A template parm.  We substitute the corresponding argument. */
3748       {
3749 	int idx;
3750 
3751 	(*mangled)++;
3752 	idx = consume_count_with_underscores (mangled);
3753 
3754 	if (idx == -1
3755 	    || (work->tmpl_argvec && idx >= work->ntmpl_args)
3756 	    || consume_count_with_underscores (mangled) == -1)
3757 	  {
3758 	    success = 0;
3759 	    break;
3760 	  }
3761 
3762 	if (work->tmpl_argvec)
3763 	  string_append (result, work->tmpl_argvec[idx]);
3764 	else
3765 	  string_append_template_idx (result, idx);
3766 
3767 	success = 1;
3768       }
3769     break;
3770 
3771     default:
3772       success = demangle_fund_type (work, mangled, result);
3773       if (tk == tk_none)
3774 	tk = (type_kind_t) success;
3775       break;
3776     }
3777 
3778   if (success)
3779     {
3780       if (!STRING_EMPTY (&decl))
3781 	{
3782 	  string_append (result, " ");
3783 	  string_appends (result, &decl);
3784 	}
3785     }
3786   else
3787     string_delete (result);
3788   string_delete (&decl);
3789 
3790   if (success)
3791     /* Assume an integral type, if we're not sure.  */
3792     return (int) ((tk == tk_none) ? tk_integral : tk);
3793   else
3794     return 0;
3795 }
3796 
3797 /* Given a pointer to a type string that represents a fundamental type
3798    argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3799    string in which the demangled output is being built in RESULT, and
3800    the WORK structure, decode the types and add them to the result.
3801 
3802    For example:
3803 
3804    	"Ci"	=>	"const int"
3805 	"Sl"	=>	"signed long"
3806 	"CUs"	=>	"const unsigned short"
3807 
3808    The value returned is really a type_kind_t.  */
3809 
3810 static int
3811 demangle_fund_type (work, mangled, result)
3812      struct work_stuff *work;
3813      const char **mangled;
3814      string *result;
3815 {
3816   int done = 0;
3817   int success = 1;
3818   char buf[10];
3819   unsigned int dec = 0;
3820   type_kind_t tk = tk_integral;
3821 
3822   /* First pick off any type qualifiers.  There can be more than one.  */
3823 
3824   while (!done)
3825     {
3826       switch (**mangled)
3827 	{
3828 	case 'C':
3829 	case 'V':
3830 	case 'u':
3831 	  if (PRINT_ANSI_QUALIFIERS)
3832 	    {
3833               if (!STRING_EMPTY (result))
3834                 string_prepend (result, " ");
3835 	      string_prepend (result, demangle_qualifier (**mangled));
3836 	    }
3837 	  (*mangled)++;
3838 	  break;
3839 	case 'U':
3840 	  (*mangled)++;
3841 	  APPEND_BLANK (result);
3842 	  string_append (result, "unsigned");
3843 	  break;
3844 	case 'S': /* signed char only */
3845 	  (*mangled)++;
3846 	  APPEND_BLANK (result);
3847 	  string_append (result, "signed");
3848 	  break;
3849 	case 'J':
3850 	  (*mangled)++;
3851 	  APPEND_BLANK (result);
3852 	  string_append (result, "__complex");
3853 	  break;
3854 	default:
3855 	  done = 1;
3856 	  break;
3857 	}
3858     }
3859 
3860   /* Now pick off the fundamental type.  There can be only one.  */
3861 
3862   switch (**mangled)
3863     {
3864     case '\0':
3865     case '_':
3866       break;
3867     case 'v':
3868       (*mangled)++;
3869       APPEND_BLANK (result);
3870       string_append (result, "void");
3871       break;
3872     case 'x':
3873       (*mangled)++;
3874       APPEND_BLANK (result);
3875       string_append (result, "long long");
3876       break;
3877     case 'l':
3878       (*mangled)++;
3879       APPEND_BLANK (result);
3880       string_append (result, "long");
3881       break;
3882     case 'i':
3883       (*mangled)++;
3884       APPEND_BLANK (result);
3885       string_append (result, "int");
3886       break;
3887     case 's':
3888       (*mangled)++;
3889       APPEND_BLANK (result);
3890       string_append (result, "short");
3891       break;
3892     case 'b':
3893       (*mangled)++;
3894       APPEND_BLANK (result);
3895       string_append (result, "bool");
3896       tk = tk_bool;
3897       break;
3898     case 'c':
3899       (*mangled)++;
3900       APPEND_BLANK (result);
3901       string_append (result, "char");
3902       tk = tk_char;
3903       break;
3904     case 'w':
3905       (*mangled)++;
3906       APPEND_BLANK (result);
3907       string_append (result, "wchar_t");
3908       tk = tk_char;
3909       break;
3910     case 'r':
3911       (*mangled)++;
3912       APPEND_BLANK (result);
3913       string_append (result, "long double");
3914       tk = tk_real;
3915       break;
3916     case 'd':
3917       (*mangled)++;
3918       APPEND_BLANK (result);
3919       string_append (result, "double");
3920       tk = tk_real;
3921       break;
3922     case 'f':
3923       (*mangled)++;
3924       APPEND_BLANK (result);
3925       string_append (result, "float");
3926       tk = tk_real;
3927       break;
3928     case 'G':
3929       (*mangled)++;
3930       if (!ISDIGIT ((unsigned char)**mangled))
3931 	{
3932 	  success = 0;
3933 	  break;
3934 	}
3935     case 'I':
3936       (*mangled)++;
3937       if (**mangled == '_')
3938 	{
3939 	  int i;
3940 	  (*mangled)++;
3941 	  for (i = 0;
3942 	       i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
3943 	       (*mangled)++, i++)
3944 	    buf[i] = **mangled;
3945 	  if (**mangled != '_')
3946 	    {
3947 	      success = 0;
3948 	      break;
3949 	    }
3950 	  buf[i] = '\0';
3951 	  (*mangled)++;
3952 	}
3953       else
3954 	{
3955 	  strncpy (buf, *mangled, 2);
3956 	  buf[2] = '\0';
3957 	  *mangled += min (strlen (*mangled), 2);
3958 	}
3959       sscanf (buf, "%x", &dec);
3960       snprintf (buf, sizeof buf, "int%u_t", dec);
3961       APPEND_BLANK (result);
3962       string_append (result, buf);
3963       break;
3964 
3965       /* fall through */
3966       /* An explicit type, such as "6mytype" or "7integer" */
3967     case '0':
3968     case '1':
3969     case '2':
3970     case '3':
3971     case '4':
3972     case '5':
3973     case '6':
3974     case '7':
3975     case '8':
3976     case '9':
3977       {
3978         int bindex = register_Btype (work);
3979         string btype;
3980         string_init (&btype);
3981         if (demangle_class_name (work, mangled, &btype)) {
3982           remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3983           APPEND_BLANK (result);
3984           string_appends (result, &btype);
3985         }
3986         else
3987           success = 0;
3988         string_delete (&btype);
3989         break;
3990       }
3991     case 't':
3992       {
3993         string btype;
3994         string_init (&btype);
3995         success = demangle_template (work, mangled, &btype, 0, 1, 1);
3996         string_appends (result, &btype);
3997         string_delete (&btype);
3998         break;
3999       }
4000     default:
4001       success = 0;
4002       break;
4003     }
4004 
4005   return success ? ((int) tk) : 0;
4006 }
4007 
4008 
4009 /* Handle a template's value parameter for HP aCC (extension from ARM)
4010    **mangled points to 'S' or 'U' */
4011 
4012 static int
4013 do_hpacc_template_const_value (work, mangled, result)
4014      struct work_stuff *work ATTRIBUTE_UNUSED;
4015      const char **mangled;
4016      string *result;
4017 {
4018   int unsigned_const;
4019 
4020   if (**mangled != 'U' && **mangled != 'S')
4021     return 0;
4022 
4023   unsigned_const = (**mangled == 'U');
4024 
4025   (*mangled)++;
4026 
4027   switch (**mangled)
4028     {
4029       case 'N':
4030         string_append (result, "-");
4031         /* fall through */
4032       case 'P':
4033         (*mangled)++;
4034         break;
4035       case 'M':
4036         /* special case for -2^31 */
4037         string_append (result, "-2147483648");
4038         (*mangled)++;
4039         return 1;
4040       default:
4041         return 0;
4042     }
4043 
4044   /* We have to be looking at an integer now */
4045   if (!(ISDIGIT ((unsigned char)**mangled)))
4046     return 0;
4047 
4048   /* We only deal with integral values for template
4049      parameters -- so it's OK to look only for digits */
4050   while (ISDIGIT ((unsigned char)**mangled))
4051     {
4052       char_str[0] = **mangled;
4053       string_append (result, char_str);
4054       (*mangled)++;
4055     }
4056 
4057   if (unsigned_const)
4058     string_append (result, "U");
4059 
4060   /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4061      with L or LL suffixes. pai/1997-09-03 */
4062 
4063   return 1; /* success */
4064 }
4065 
4066 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4067    **mangled is pointing to the 'A' */
4068 
4069 static int
4070 do_hpacc_template_literal (work, mangled, result)
4071      struct work_stuff *work;
4072      const char **mangled;
4073      string *result;
4074 {
4075   int literal_len = 0;
4076   char * recurse;
4077   char * recurse_dem;
4078 
4079   if (**mangled != 'A')
4080     return 0;
4081 
4082   (*mangled)++;
4083 
4084   literal_len = consume_count (mangled);
4085 
4086   if (literal_len <= 0)
4087     return 0;
4088 
4089   /* Literal parameters are names of arrays, functions, etc.  and the
4090      canonical representation uses the address operator */
4091   string_append (result, "&");
4092 
4093   /* Now recursively demangle the literal name */
4094   recurse = (char *) xmalloc (literal_len + 1);
4095   memcpy (recurse, *mangled, literal_len);
4096   recurse[literal_len] = '\000';
4097 
4098   recurse_dem = cplus_demangle (recurse, work->options);
4099 
4100   if (recurse_dem)
4101     {
4102       string_append (result, recurse_dem);
4103       free (recurse_dem);
4104     }
4105   else
4106     {
4107       string_appendn (result, *mangled, literal_len);
4108     }
4109   (*mangled) += literal_len;
4110   free (recurse);
4111 
4112   return 1;
4113 }
4114 
4115 static int
4116 snarf_numeric_literal (args, arg)
4117      const char ** args;
4118      string * arg;
4119 {
4120   if (**args == '-')
4121     {
4122       char_str[0] = '-';
4123       string_append (arg, char_str);
4124       (*args)++;
4125     }
4126   else if (**args == '+')
4127     (*args)++;
4128 
4129   if (!ISDIGIT ((unsigned char)**args))
4130     return 0;
4131 
4132   while (ISDIGIT ((unsigned char)**args))
4133     {
4134       char_str[0] = **args;
4135       string_append (arg, char_str);
4136       (*args)++;
4137     }
4138 
4139   return 1;
4140 }
4141 
4142 /* Demangle the next argument, given by MANGLED into RESULT, which
4143    *should be an uninitialized* string.  It will be initialized here,
4144    and free'd should anything go wrong.  */
4145 
4146 static int
4147 do_arg (work, mangled, result)
4148      struct work_stuff *work;
4149      const char **mangled;
4150      string *result;
4151 {
4152   /* Remember where we started so that we can record the type, for
4153      non-squangling type remembering.  */
4154   const char *start = *mangled;
4155 
4156   string_init (result);
4157 
4158   if (work->nrepeats > 0)
4159     {
4160       --work->nrepeats;
4161 
4162       if (work->previous_argument == 0)
4163 	return 0;
4164 
4165       /* We want to reissue the previous type in this argument list.  */
4166       string_appends (result, work->previous_argument);
4167       return 1;
4168     }
4169 
4170   if (**mangled == 'n')
4171     {
4172       /* A squangling-style repeat.  */
4173       (*mangled)++;
4174       work->nrepeats = consume_count(mangled);
4175 
4176       if (work->nrepeats <= 0)
4177 	/* This was not a repeat count after all.  */
4178 	return 0;
4179 
4180       if (work->nrepeats > 9)
4181 	{
4182 	  if (**mangled != '_')
4183 	    /* The repeat count should be followed by an '_' in this
4184 	       case.  */
4185 	    return 0;
4186 	  else
4187 	    (*mangled)++;
4188 	}
4189 
4190       /* Now, the repeat is all set up.  */
4191       return do_arg (work, mangled, result);
4192     }
4193 
4194   /* Save the result in WORK->previous_argument so that we can find it
4195      if it's repeated.  Note that saving START is not good enough: we
4196      do not want to add additional types to the back-referenceable
4197      type vector when processing a repeated type.  */
4198   if (work->previous_argument)
4199     string_delete (work->previous_argument);
4200   else
4201     work->previous_argument = (string*) xmalloc (sizeof (string));
4202 
4203   if (!do_type (work, mangled, work->previous_argument))
4204     return 0;
4205 
4206   string_appends (result, work->previous_argument);
4207 
4208   remember_type (work, start, *mangled - start);
4209   return 1;
4210 }
4211 
4212 static void
4213 remember_type (work, start, len)
4214      struct work_stuff *work;
4215      const char *start;
4216      int len;
4217 {
4218   char *tem;
4219 
4220   if (work->forgetting_types)
4221     return;
4222 
4223   if (work -> ntypes >= work -> typevec_size)
4224     {
4225       if (work -> typevec_size == 0)
4226 	{
4227 	  work -> typevec_size = 3;
4228 	  work -> typevec
4229 	    = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
4230 	}
4231       else
4232 	{
4233 	  work -> typevec_size *= 2;
4234 	  work -> typevec
4235 	    = (char **) xrealloc ((char *)work -> typevec,
4236 				  sizeof (char *) * work -> typevec_size);
4237 	}
4238     }
4239   tem = xmalloc (len + 1);
4240   memcpy (tem, start, len);
4241   tem[len] = '\0';
4242   work -> typevec[work -> ntypes++] = tem;
4243 }
4244 
4245 
4246 /* Remember a K type class qualifier. */
4247 static void
4248 remember_Ktype (work, start, len)
4249      struct work_stuff *work;
4250      const char *start;
4251      int len;
4252 {
4253   char *tem;
4254 
4255   if (work -> numk >= work -> ksize)
4256     {
4257       if (work -> ksize == 0)
4258 	{
4259 	  work -> ksize = 5;
4260 	  work -> ktypevec
4261 	    = (char **) xmalloc (sizeof (char *) * work -> ksize);
4262 	}
4263       else
4264 	{
4265 	  work -> ksize *= 2;
4266 	  work -> ktypevec
4267 	    = (char **) xrealloc ((char *)work -> ktypevec,
4268 				  sizeof (char *) * work -> ksize);
4269 	}
4270     }
4271   tem = xmalloc (len + 1);
4272   memcpy (tem, start, len);
4273   tem[len] = '\0';
4274   work -> ktypevec[work -> numk++] = tem;
4275 }
4276 
4277 /* Register a B code, and get an index for it. B codes are registered
4278    as they are seen, rather than as they are completed, so map<temp<char> >
4279    registers map<temp<char> > as B0, and temp<char> as B1 */
4280 
4281 static int
4282 register_Btype (work)
4283      struct work_stuff *work;
4284 {
4285   int ret;
4286 
4287   if (work -> numb >= work -> bsize)
4288     {
4289       if (work -> bsize == 0)
4290 	{
4291 	  work -> bsize = 5;
4292 	  work -> btypevec
4293 	    = (char **) xmalloc (sizeof (char *) * work -> bsize);
4294 	}
4295       else
4296 	{
4297 	  work -> bsize *= 2;
4298 	  work -> btypevec
4299 	    = (char **) xrealloc ((char *)work -> btypevec,
4300 				  sizeof (char *) * work -> bsize);
4301 	}
4302     }
4303   ret = work -> numb++;
4304   work -> btypevec[ret] = NULL;
4305   return(ret);
4306 }
4307 
4308 /* Store a value into a previously registered B code type. */
4309 
4310 static void
4311 remember_Btype (work, start, len, index)
4312      struct work_stuff *work;
4313      const char *start;
4314      int len, index;
4315 {
4316   char *tem;
4317 
4318   tem = xmalloc (len + 1);
4319   memcpy (tem, start, len);
4320   tem[len] = '\0';
4321   work -> btypevec[index] = tem;
4322 }
4323 
4324 /* Lose all the info related to B and K type codes. */
4325 static void
4326 forget_B_and_K_types (work)
4327      struct work_stuff *work;
4328 {
4329   int i;
4330 
4331   while (work -> numk > 0)
4332     {
4333       i = --(work -> numk);
4334       if (work -> ktypevec[i] != NULL)
4335 	{
4336 	  free (work -> ktypevec[i]);
4337 	  work -> ktypevec[i] = NULL;
4338 	}
4339     }
4340 
4341   while (work -> numb > 0)
4342     {
4343       i = --(work -> numb);
4344       if (work -> btypevec[i] != NULL)
4345 	{
4346 	  free (work -> btypevec[i]);
4347 	  work -> btypevec[i] = NULL;
4348 	}
4349     }
4350 }
4351 /* Forget the remembered types, but not the type vector itself.  */
4352 
4353 static void
4354 forget_types (work)
4355      struct work_stuff *work;
4356 {
4357   int i;
4358 
4359   while (work -> ntypes > 0)
4360     {
4361       i = --(work -> ntypes);
4362       if (work -> typevec[i] != NULL)
4363 	{
4364 	  free (work -> typevec[i]);
4365 	  work -> typevec[i] = NULL;
4366 	}
4367     }
4368 }
4369 
4370 /* Process the argument list part of the signature, after any class spec
4371    has been consumed, as well as the first 'F' character (if any).  For
4372    example:
4373 
4374    "__als__3fooRT0"		=>	process "RT0"
4375    "complexfunc5__FPFPc_PFl_i"	=>	process "PFPc_PFl_i"
4376 
4377    DECLP must be already initialised, usually non-empty.  It won't be freed
4378    on failure.
4379 
4380    Note that g++ differs significantly from ARM and lucid style mangling
4381    with regards to references to previously seen types.  For example, given
4382    the source fragment:
4383 
4384      class foo {
4385        public:
4386        foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4387      };
4388 
4389      foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4390      void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4391 
4392    g++ produces the names:
4393 
4394      __3fooiRT0iT2iT2
4395      foo__FiR3fooiT1iT1
4396 
4397    while lcc (and presumably other ARM style compilers as well) produces:
4398 
4399      foo__FiR3fooT1T2T1T2
4400      __ct__3fooFiR3fooT1T2T1T2
4401 
4402    Note that g++ bases its type numbers starting at zero and counts all
4403    previously seen types, while lucid/ARM bases its type numbers starting
4404    at one and only considers types after it has seen the 'F' character
4405    indicating the start of the function args.  For lucid/ARM style, we
4406    account for this difference by discarding any previously seen types when
4407    we see the 'F' character, and subtracting one from the type number
4408    reference.
4409 
4410  */
4411 
4412 static int
4413 demangle_args (work, mangled, declp)
4414      struct work_stuff *work;
4415      const char **mangled;
4416      string *declp;
4417 {
4418   string arg;
4419   int need_comma = 0;
4420   int r;
4421   int t;
4422   const char *tem;
4423   char temptype;
4424 
4425   if (PRINT_ARG_TYPES)
4426     {
4427       string_append (declp, "(");
4428       if (**mangled == '\0')
4429 	{
4430 	  string_append (declp, "void");
4431 	}
4432     }
4433 
4434   while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4435 	 || work->nrepeats > 0)
4436     {
4437       if ((**mangled == 'N') || (**mangled == 'T'))
4438 	{
4439 	  temptype = *(*mangled)++;
4440 
4441 	  if (temptype == 'N')
4442 	    {
4443 	      if (!get_count (mangled, &r))
4444 		{
4445 		  return (0);
4446 		}
4447 	    }
4448 	  else
4449 	    {
4450 	      r = 1;
4451 	    }
4452           if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
4453             {
4454               /* If we have 10 or more types we might have more than a 1 digit
4455                  index so we'll have to consume the whole count here. This
4456                  will lose if the next thing is a type name preceded by a
4457                  count but it's impossible to demangle that case properly
4458                  anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4459                  Pc, ...)"  or "(..., type12, char *, ...)" */
4460               if ((t = consume_count(mangled)) <= 0)
4461                 {
4462                   return (0);
4463                 }
4464             }
4465           else
4466 	    {
4467 	      if (!get_count (mangled, &t))
4468 	    	{
4469 	          return (0);
4470 	    	}
4471 	    }
4472 	  if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4473 	    {
4474 	      t--;
4475 	    }
4476 	  /* Validate the type index.  Protect against illegal indices from
4477 	     malformed type strings.  */
4478 	  if ((t < 0) || (t >= work -> ntypes))
4479 	    {
4480 	      return (0);
4481 	    }
4482 	  while (work->nrepeats > 0 || --r >= 0)
4483 	    {
4484 	      tem = work -> typevec[t];
4485 	      if (need_comma && PRINT_ARG_TYPES)
4486 		{
4487 		  string_append (declp, ", ");
4488 		}
4489 	      if (!do_arg (work, &tem, &arg))
4490 		{
4491 		  return (0);
4492 		}
4493 	      if (PRINT_ARG_TYPES)
4494 		{
4495 		  string_appends (declp, &arg);
4496 		}
4497 	      string_delete (&arg);
4498 	      need_comma = 1;
4499 	    }
4500 	}
4501       else
4502 	{
4503 	  if (need_comma && PRINT_ARG_TYPES)
4504 	    string_append (declp, ", ");
4505 	  if (!do_arg (work, mangled, &arg))
4506 	    return (0);
4507 	  if (PRINT_ARG_TYPES)
4508 	    string_appends (declp, &arg);
4509 	  string_delete (&arg);
4510 	  need_comma = 1;
4511 	}
4512     }
4513 
4514   if (**mangled == 'e')
4515     {
4516       (*mangled)++;
4517       if (PRINT_ARG_TYPES)
4518 	{
4519 	  if (need_comma)
4520 	    {
4521 	      string_append (declp, ",");
4522 	    }
4523 	  string_append (declp, "...");
4524 	}
4525     }
4526 
4527   if (PRINT_ARG_TYPES)
4528     {
4529       string_append (declp, ")");
4530     }
4531   return (1);
4532 }
4533 
4534 /* Like demangle_args, but for demangling the argument lists of function
4535    and method pointers or references, not top-level declarations.  */
4536 
4537 static int
4538 demangle_nested_args (work, mangled, declp)
4539      struct work_stuff *work;
4540      const char **mangled;
4541      string *declp;
4542 {
4543   string* saved_previous_argument;
4544   int result;
4545   int saved_nrepeats;
4546 
4547   /* The G++ name-mangling algorithm does not remember types on nested
4548      argument lists, unless -fsquangling is used, and in that case the
4549      type vector updated by remember_type is not used.  So, we turn
4550      off remembering of types here.  */
4551   ++work->forgetting_types;
4552 
4553   /* For the repeat codes used with -fsquangling, we must keep track of
4554      the last argument.  */
4555   saved_previous_argument = work->previous_argument;
4556   saved_nrepeats = work->nrepeats;
4557   work->previous_argument = 0;
4558   work->nrepeats = 0;
4559 
4560   /* Actually demangle the arguments.  */
4561   result = demangle_args (work, mangled, declp);
4562 
4563   /* Restore the previous_argument field.  */
4564   if (work->previous_argument)
4565     {
4566       string_delete (work->previous_argument);
4567       free ((char *) work->previous_argument);
4568     }
4569   work->previous_argument = saved_previous_argument;
4570   --work->forgetting_types;
4571   work->nrepeats = saved_nrepeats;
4572 
4573   return result;
4574 }
4575 
4576 static void
4577 demangle_function_name (work, mangled, declp, scan)
4578      struct work_stuff *work;
4579      const char **mangled;
4580      string *declp;
4581      const char *scan;
4582 {
4583   size_t i;
4584   string type;
4585   const char *tem;
4586 
4587   string_appendn (declp, (*mangled), scan - (*mangled));
4588   string_need (declp, 1);
4589   *(declp -> p) = '\0';
4590 
4591   /* Consume the function name, including the "__" separating the name
4592      from the signature.  We are guaranteed that SCAN points to the
4593      separator.  */
4594 
4595   (*mangled) = scan + 2;
4596   /* We may be looking at an instantiation of a template function:
4597      foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4598      following _F marks the start of the function arguments.  Handle
4599      the template arguments first. */
4600 
4601   if (HP_DEMANGLING && (**mangled == 'X'))
4602     {
4603       demangle_arm_hp_template (work, mangled, 0, declp);
4604       /* This leaves MANGLED pointing to the 'F' marking func args */
4605     }
4606 
4607   if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4608     {
4609 
4610       /* See if we have an ARM style constructor or destructor operator.
4611 	 If so, then just record it, clear the decl, and return.
4612 	 We can't build the actual constructor/destructor decl until later,
4613 	 when we recover the class name from the signature.  */
4614 
4615       if (strcmp (declp -> b, "__ct") == 0)
4616 	{
4617 	  work -> constructor += 1;
4618 	  string_clear (declp);
4619 	  return;
4620 	}
4621       else if (strcmp (declp -> b, "__dt") == 0)
4622 	{
4623 	  work -> destructor += 1;
4624 	  string_clear (declp);
4625 	  return;
4626 	}
4627     }
4628 
4629   if (declp->p - declp->b >= 3
4630       && declp->b[0] == 'o'
4631       && declp->b[1] == 'p'
4632       && strchr (cplus_markers, declp->b[2]) != NULL)
4633     {
4634       /* see if it's an assignment expression */
4635       if (declp->p - declp->b >= 10 /* op$assign_ */
4636 	  && memcmp (declp->b + 3, "assign_", 7) == 0)
4637 	{
4638 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
4639 	    {
4640 	      int len = declp->p - declp->b - 10;
4641 	      if ((int) strlen (optable[i].in) == len
4642 		  && memcmp (optable[i].in, declp->b + 10, len) == 0)
4643 		{
4644 		  string_clear (declp);
4645 		  string_append (declp, "operator");
4646 		  string_append (declp, optable[i].out);
4647 		  string_append (declp, "=");
4648 		  break;
4649 		}
4650 	    }
4651 	}
4652       else
4653 	{
4654 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
4655 	    {
4656 	      int len = declp->p - declp->b - 3;
4657 	      if ((int) strlen (optable[i].in) == len
4658 		  && memcmp (optable[i].in, declp->b + 3, len) == 0)
4659 		{
4660 		  string_clear (declp);
4661 		  string_append (declp, "operator");
4662 		  string_append (declp, optable[i].out);
4663 		  break;
4664 		}
4665 	    }
4666 	}
4667     }
4668   else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4669 	   && strchr (cplus_markers, declp->b[4]) != NULL)
4670     {
4671       /* type conversion operator */
4672       tem = declp->b + 5;
4673       if (do_type (work, &tem, &type))
4674 	{
4675 	  string_clear (declp);
4676 	  string_append (declp, "operator ");
4677 	  string_appends (declp, &type);
4678 	  string_delete (&type);
4679 	}
4680     }
4681   else if (declp->b[0] == '_' && declp->b[1] == '_'
4682 	   && declp->b[2] == 'o' && declp->b[3] == 'p')
4683     {
4684       /* ANSI.  */
4685       /* type conversion operator.  */
4686       tem = declp->b + 4;
4687       if (do_type (work, &tem, &type))
4688 	{
4689 	  string_clear (declp);
4690 	  string_append (declp, "operator ");
4691 	  string_appends (declp, &type);
4692 	  string_delete (&type);
4693 	}
4694     }
4695   else if (declp->b[0] == '_' && declp->b[1] == '_'
4696 	   && ISLOWER((unsigned char)declp->b[2])
4697 	   && ISLOWER((unsigned char)declp->b[3]))
4698     {
4699       if (declp->b[4] == '\0')
4700 	{
4701 	  /* Operator.  */
4702 	  for (i = 0; i < ARRAY_SIZE (optable); i++)
4703 	    {
4704 	      if (strlen (optable[i].in) == 2
4705 		  && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4706 		{
4707 		  string_clear (declp);
4708 		  string_append (declp, "operator");
4709 		  string_append (declp, optable[i].out);
4710 		  break;
4711 		}
4712 	    }
4713 	}
4714       else
4715 	{
4716 	  if (declp->b[2] == 'a' && declp->b[5] == '\0')
4717 	    {
4718 	      /* Assignment.  */
4719 	      for (i = 0; i < ARRAY_SIZE (optable); i++)
4720 		{
4721 		  if (strlen (optable[i].in) == 3
4722 		      && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4723 		    {
4724 		      string_clear (declp);
4725 		      string_append (declp, "operator");
4726 		      string_append (declp, optable[i].out);
4727 		      break;
4728 		    }
4729 		}
4730 	    }
4731 	}
4732     }
4733 }
4734 
4735 /* a mini string-handling package */
4736 
4737 static void
4738 string_need (s, n)
4739      string *s;
4740      int n;
4741 {
4742   int tem;
4743 
4744   if (s->b == NULL)
4745     {
4746       if (n < 32)
4747 	{
4748 	  n = 32;
4749 	}
4750       s->p = s->b = xmalloc (n);
4751       s->e = s->b + n;
4752     }
4753   else if (s->e - s->p < n)
4754     {
4755       tem = s->p - s->b;
4756       n += tem;
4757       n *= 2;
4758       s->b = xrealloc (s->b, n);
4759       s->p = s->b + tem;
4760       s->e = s->b + n;
4761     }
4762 }
4763 
4764 static void
4765 string_delete (s)
4766      string *s;
4767 {
4768   if (s->b != NULL)
4769     {
4770       free (s->b);
4771       s->b = s->e = s->p = NULL;
4772     }
4773 }
4774 
4775 static void
4776 string_init (s)
4777      string *s;
4778 {
4779   s->b = s->p = s->e = NULL;
4780 }
4781 
4782 static void
4783 string_clear (s)
4784      string *s;
4785 {
4786   s->p = s->b;
4787 }
4788 
4789 #if 0
4790 
4791 static int
4792 string_empty (s)
4793      string *s;
4794 {
4795   return (s->b == s->p);
4796 }
4797 
4798 #endif
4799 
4800 static void
4801 string_append (p, s)
4802      string *p;
4803      const char *s;
4804 {
4805   int n;
4806   if (s == NULL || *s == '\0')
4807     return;
4808   n = strlen (s);
4809   string_need (p, n);
4810   memcpy (p->p, s, n);
4811   p->p += n;
4812 }
4813 
4814 static void
4815 string_appends (p, s)
4816      string *p, *s;
4817 {
4818   int n;
4819 
4820   if (s->b != s->p)
4821     {
4822       n = s->p - s->b;
4823       string_need (p, n);
4824       memcpy (p->p, s->b, n);
4825       p->p += n;
4826     }
4827 }
4828 
4829 static void
4830 string_appendn (p, s, n)
4831      string *p;
4832      const char *s;
4833      int n;
4834 {
4835   if (n != 0)
4836     {
4837       string_need (p, n);
4838       memcpy (p->p, s, n);
4839       p->p += n;
4840     }
4841 }
4842 
4843 static void
4844 string_prepend (p, s)
4845      string *p;
4846      const char *s;
4847 {
4848   if (s != NULL && *s != '\0')
4849     {
4850       string_prependn (p, s, strlen (s));
4851     }
4852 }
4853 
4854 static void
4855 string_prepends (p, s)
4856      string *p, *s;
4857 {
4858   if (s->b != s->p)
4859     {
4860       string_prependn (p, s->b, s->p - s->b);
4861     }
4862 }
4863 
4864 static void
4865 string_prependn (p, s, n)
4866      string *p;
4867      const char *s;
4868      int n;
4869 {
4870   char *q;
4871 
4872   if (n != 0)
4873     {
4874       string_need (p, n);
4875       for (q = p->p - 1; q >= p->b; q--)
4876 	{
4877 	  q[n] = q[0];
4878 	}
4879       memcpy (p->b, s, n);
4880       p->p += n;
4881     }
4882 }
4883 
4884 static void
4885 string_append_template_idx (s, idx)
4886      string *s;
4887      int idx;
4888 {
4889   char buf[INTBUF_SIZE + 1 /* 'T' */];
4890   snprintf(buf, sizeof buf, "T%d", idx);
4891   string_append (s, buf);
4892 }
4893