changed calling convention for Q_enter_global_ref
[deliverable/binutils-gdb.git] / gdb / cplus-dem.c
CommitLineData
dd3b648e 1/* Demangler for GNU C++
7d9884b9 2 Copyright 1989, 1991 Free Software Foundation, Inc.
dd3b648e
RP
3 written by James Clark (jjc@jclark.uucp)
4
572acbbe
MT
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
99a7de40 9
572acbbe
MT
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
99a7de40 14
572acbbe
MT
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
dd3b648e 18
7d9884b9 19/* This is for g++ 1.95.03 (November 13 verison). */
dd3b648e 20
8f793aa5 21/* This file exports two functions; cplus_mangle_opname and cplus_demangle.
dd3b648e
RP
22
23 This file imports xmalloc and xrealloc, which are like malloc and
24 realloc except that they generate a fatal error if there is no
25 available memory. */
26
27/* define this if names don't start with _ */
28/* #define nounderscore 1 */
29
e1ce8aa5
JK
30/* GDB-specific, FIXME. */
31#include "defs.h"
8f793aa5 32#include "demangle.h"
e1ce8aa5 33
d747e0af
MT
34#include <ctype.h>
35
dd3b648e
RP
36#ifdef USG
37#include <memory.h>
38#include <string.h>
39#else
40#include <strings.h>
dd3b648e
RP
41#endif
42
8ffd75c8
JG
43/* This is '$' on systems where the assembler can deal with that.
44 Where the assembler can't, it's '.' (but on many systems '.' is
45 used for other things). */
46#if !defined (CPLUS_MARKER)
47#define CPLUS_MARKER '$'
48#endif
49
dd3b648e
RP
50#ifndef __STDC__
51#define const
52#endif
53
54#ifdef __STDC__
8f793aa5
FF
55extern char *cplus_demangle (const char *type, int options);
56extern char *cplus_mangle_opname (char *opname, int options);
dd3b648e
RP
57#else
58extern char *cplus_demangle ();
8f793aa5 59extern char *cplus_mangle_opname ();
dd3b648e
RP
60#endif
61
f536aa39
PB
62/* Stuff that is shared betwen sub-routines.
63 * Using a shared structure allows cplus_demange to be reentrant. */
64
65struct work_stuff {
8f793aa5 66 int options;
f536aa39
PB
67 char **typevec;
68 int ntypes;
69 int typevec_size;
70};
dd3b648e 71
ef98d5ac 72const static struct optable {
dd3b648e
RP
73 const char *in;
74 const char *out;
8f793aa5 75 int flags;
dd3b648e 76} optable[] = {
8f793aa5
FF
77 "nw", " new", DMGL_ANSI, /* new (1.92, ansi) */
78 "dl", " delete", DMGL_ANSI, /* new (1.92, ansi) */
79 "new", " new", 0, /* old (1.91, and 1.x) */
80 "delete", " delete", 0, /* old (1.91, and 1.x) */
81 "as", "=", DMGL_ANSI, /* ansi */
82 "ne", "!=", DMGL_ANSI, /* old, ansi */
83 "eq", "==", DMGL_ANSI, /* old, ansi */
84 "ge", ">=", DMGL_ANSI, /* old, ansi */
85 "gt", ">", DMGL_ANSI, /* old, ansi */
86 "le", "<=", DMGL_ANSI, /* old, ansi */
87 "lt", "<", DMGL_ANSI, /* old, ansi */
88 "plus", "+", 0, /* old */
89 "pl", "+", DMGL_ANSI, /* ansi */
90 "apl", "+=", DMGL_ANSI, /* ansi */
91 "minus", "-", 0, /* old */
92 "mi", "-", DMGL_ANSI, /* ansi */
93 "ami", "-=", DMGL_ANSI, /* ansi */
94 "mult", "*", 0, /* old */
95 "ml", "*", DMGL_ANSI, /* ansi */
96 "aml", "*=", DMGL_ANSI, /* ansi */
97 "convert", "+", 0, /* old (unary +) */
98 "negate", "-", 0, /* old (unary -) */
99 "trunc_mod", "%", 0, /* old */
100 "md", "%", DMGL_ANSI, /* ansi */
101 "amd", "%=", DMGL_ANSI, /* ansi */
102 "trunc_div", "/", 0, /* old */
103 "dv", "/", DMGL_ANSI, /* ansi */
104 "adv", "/=", DMGL_ANSI, /* ansi */
105 "truth_andif", "&&", 0, /* old */
106 "aa", "&&", DMGL_ANSI, /* ansi */
107 "truth_orif", "||", 0, /* old */
108 "oo", "||", DMGL_ANSI, /* ansi */
109 "truth_not", "!", 0, /* old */
110 "nt", "!", DMGL_ANSI, /* ansi */
111 "postincrement","++", 0, /* old */
112 "pp", "++", DMGL_ANSI, /* ansi */
113 "postdecrement","--", 0, /* old */
114 "mm", "--", DMGL_ANSI, /* ansi */
115 "bit_ior", "|", 0, /* old */
116 "or", "|", DMGL_ANSI, /* ansi */
117 "aor", "|=", DMGL_ANSI, /* ansi */
118 "bit_xor", "^", 0, /* old */
119 "er", "^", DMGL_ANSI, /* ansi */
120 "aer", "^=", DMGL_ANSI, /* ansi */
121 "bit_and", "&", 0, /* old */
122 "ad", "&", DMGL_ANSI, /* ansi */
123 "aad", "&=", DMGL_ANSI, /* ansi */
124 "bit_not", "~", 0, /* old */
125 "co", "~", DMGL_ANSI, /* ansi */
126 "call", "()", 0, /* old */
127 "cl", "()", DMGL_ANSI, /* ansi */
128 "alshift", "<<", 0, /* old */
129 "ls", "<<", DMGL_ANSI, /* ansi */
130 "als", "<<=", DMGL_ANSI, /* ansi */
131 "arshift", ">>", 0, /* old */
132 "rs", ">>", DMGL_ANSI, /* ansi */
133 "ars", ">>=", DMGL_ANSI, /* ansi */
134 "component", "->", 0, /* old */
135 "rf", "->", DMGL_ANSI, /* ansi */
136 "indirect", "*", 0, /* old */
137 "method_call", "->()", 0, /* old */
138 "addr", "&", 0, /* old (unary &) */
139 "array", "[]", 0, /* old */
140 "vc", "[]", DMGL_ANSI, /* ansi */
141 "compound", ", ", 0, /* old */
142 "cm", ", ", DMGL_ANSI, /* ansi */
143 "cond", "?:", 0, /* old */
144 "cn", "?:", DMGL_ANSI, /* psuedo-ansi */
145 "max", ">?", 0, /* old */
146 "mx", ">?", DMGL_ANSI, /* psuedo-ansi */
147 "min", "<?", 0, /* old */
148 "mn", "<?", DMGL_ANSI, /* psuedo-ansi */
149 "nop", "", 0, /* old (for operator=) */
150 "rm", "->*", DMGL_ANSI, /* ansi */
dd3b648e
RP
151};
152
153/* Beware: these aren't '\0' terminated. */
154
ef98d5ac 155typedef struct string {
dd3b648e
RP
156 char *b; /* pointer to start of string */
157 char *p; /* pointer after last character */
158 char *e; /* pointer after end of allocated space */
159} string;
160
1ab3bf1b
JG
161static void
162string_need PARAMS ((string *, int));
163
164static void
165string_delete PARAMS ((string *));
166
167static void
168string_init PARAMS ((string *));
169
170static void
171string_clear PARAMS ((string *));
172
173static int
174string_empty PARAMS ((string *));
175
176static void
177string_append PARAMS ((string *, const char *));
178
179static void
180string_appends PARAMS ((string *, string *));
181
182static void
183string_appendn PARAMS ((string *, const char *, int));
184
185static void
186string_prepend PARAMS ((string *, const char *));
187
188static void
189string_prependn PARAMS ((string *, const char *, int));
190
191static int
192get_count PARAMS ((const char **, int *));
193
194static int
f536aa39 195do_args PARAMS ((const char **, string *, struct work_stuff *));
1ab3bf1b
JG
196
197static int
f536aa39 198do_type PARAMS ((const char **, string *, struct work_stuff *));
1ab3bf1b
JG
199
200static int
f536aa39 201do_arg PARAMS ((const char **, string *, struct work_stuff*));
1ab3bf1b
JG
202
203static void
f536aa39 204munge_function_name PARAMS ((string *, struct work_stuff*));
1ab3bf1b
JG
205
206static void
f536aa39 207remember_type PARAMS ((const char *, int, struct work_stuff *));
1ab3bf1b 208
dd3b648e 209#if 0
1ab3bf1b
JG
210static void
211string_prepends PARAMS ((string *, string *));
dd3b648e
RP
212#endif
213
1ab3bf1b 214
55838914 215/* Takes operator name as e.g. "++" and returns mangled
572acbbe
MT
216 operator name (e.g. "postincrement_expr"), or NULL if not found.
217
8f793aa5
FF
218 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
219 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
220
55838914 221char *
8f793aa5 222cplus_mangle_opname (opname, options)
55838914 223 char *opname;
8f793aa5 224 int options;
55838914
JK
225{
226 int i, len = strlen (opname);
55838914 227
8f793aa5 228 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
55838914
JK
229 {
230 if (strlen (optable[i].out) == len
8f793aa5 231 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
55838914 232 && memcmp (optable[i].out, opname, len) == 0)
e1ce8aa5 233 return (char *)optable[i].in;
55838914 234 }
55838914
JK
235 return 0;
236}
237
8f793aa5
FF
238/* char *cplus_demangle (const char *name, int options)
239
240 If NAME is a mangled function name produced by GNU C++, then
241 a pointer to a malloced string giving a C++ representation
242 of the name will be returned; otherwise NULL will be returned.
243 It is the caller's responsibility to free the string which
244 is returned.
245
246 The OPTIONS arg may contain one or more of the following bits:
247
248 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
249 included.
250 DMGL_PARAMS Function parameters are included.
251
252 For example,
253
254 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
255 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
256 cplus_demangle ("foo__1Ai", 0) => "A::foo"
257
258 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
259 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
260 cplus_demangle ("foo__1Afe", 0) => "A::foo"
261 */
262
dd3b648e 263char *
8f793aa5 264cplus_demangle (type, options)
dd3b648e 265 const char *type;
8f793aa5 266 int options;
dd3b648e
RP
267{
268 string decl;
269 int n;
270 int success = 0;
271 int constructor = 0;
4c53d9ca
DHW
272 int destructor = 0;
273 int static_type = 0;
dd3b648e
RP
274 int const_flag = 0;
275 int i;
f536aa39 276 struct work_stuff work[1];
dd3b648e
RP
277 const char *p;
278#ifndef LONGERNAMES
279 const char *premangle;
280#endif
281
8f793aa5
FF
282# define PRINT_ANSI_QUALIFIERS (work->options & DMGL_ANSI)
283# define PRINT_ARG_TYPES (work->options & DMGL_PARAMS)
dd3b648e
RP
284
285 if (type == NULL || *type == '\0')
286 return NULL;
287#ifndef nounderscore
288 if (*type++ != '_')
289 return NULL;
290#endif
f536aa39 291
8f793aa5 292 work->options = options;
f536aa39
PB
293 work->typevec = NULL;
294 work->ntypes = 0;
295 work->typevec_size = 0;
296
dd3b648e
RP
297 p = type;
298 while (*p != '\0' && !(*p == '_' && p[1] == '_'))
299 p++;
300 if (*p == '\0')
301 {
302 /* destructor */
f88e7af8 303 if (type[0] == '_' && type[1] == CPLUS_MARKER && type[2] == '_')
dd3b648e 304 {
0eb0a820
MT
305 int n;
306 char *tem;
307
308 type += 3; /* Get past _$_ at front. */
309 while (isdigit (*type))
310 /* If there are digits at the front, it's because
311 of new 2.0 name mangling. Just skip them. */
312 type++;
313
314 n = strlen (type)*2 + 3 + 2 + 1;
315 tem = (char *) xmalloc (n);
316 strcpy (tem, type);
572acbbe 317 strcat (tem, "::~");
0eb0a820 318 strcat (tem, type);
8f793aa5 319 if (PRINT_ARG_TYPES)
572acbbe
MT
320 strcat (tem, "()");
321 return tem;
dd3b648e
RP
322 }
323 /* static data member */
572acbbe 324 if (*type != '_' && (p = strchr (type, CPLUS_MARKER)) != NULL)
dd3b648e 325 {
572acbbe
MT
326 int n = strlen (type) + 2;
327 char *tem = (char *) xmalloc (n);
328 memcpy (tem, type, p - type);
329 strcpy (tem + (p - type), "::");
330 strcpy (tem + (p - type) + 2, p + 1);
331 return tem;
dd3b648e 332 }
572acbbe 333 /* virtual table "_vt$" */
f88e7af8 334 if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == CPLUS_MARKER)
dd3b648e 335 {
572acbbe
MT
336 int n = strlen (type + 4) + 14 + 1;
337 char *tem = (char *) xmalloc (n);
dd3b648e
RP
338 strcpy (tem, type + 4);
339 strcat (tem, " virtual table");
340 return tem;
341 }
342 return NULL;
343 }
344
345 string_init (&decl);
346
4c53d9ca
DHW
347 if (static_type)
348 {
349 if (!isdigit (p[0]) && ('t' != p[0]))
350 {
351 string_delete (&decl);
352 return NULL;
353 }
354 }
355 else if (p == type)
dd3b648e 356 {
572acbbe 357 if (!isdigit (p[2]) && ('t' != p[2]))
dd3b648e 358 {
572acbbe
MT
359 p += 1;
360 while (*p != '\0' && !(*p == '_' && p[1] == '_'))
361 p++;
1cca1729
MT
362 string_appendn (&decl, type, p - type);
363 string_need (&decl, 1);
572acbbe 364 *(decl.p) = '\0';
8f793aa5 365 munge_function_name (&decl, work); /* options ?? */
572acbbe
MT
366 if (decl.b[0] == '_')
367 {
368 string_delete (&decl);
369 return NULL;
370 }
371 else
372 p += 2;
373 }
374 else
375 {
376 constructor = 1;
377 p += 2;
dd3b648e 378 }
dd3b648e
RP
379 }
380 else
381 {
382 string_appendn (&decl, type, p - type);
1cca1729 383 string_need (&decl, 1);
572acbbe 384 *(decl.p) = '\0';
f536aa39 385 munge_function_name (&decl, work);
4c53d9ca 386 p += 2;
dd3b648e 387 }
dd3b648e
RP
388
389#ifndef LONGERNAMES
390 premangle = p;
391#endif
392 switch (*p)
393 {
f536aa39
PB
394 string class;
395 case 'Q':
396 string_init (&class);
397 n = p[1] - '0';
398 if (n < 0 || n > 9)
399 success = 0;
400 if (p[2] == '_') /* cfront style */
401 p += 1;
402 p += 2;
403 while (n-- > 0)
404 {
405 string tmp;
406 do_type (&p, &tmp, work);
407 string_appends (&class, &tmp);
408 string_append (&class, "::");
409 if (n == 0 && (constructor || destructor))
410 {
411 if (destructor)
412 string_append(&class, "~");
413 string_appends (&class, &tmp);
414 }
415 string_delete (&tmp);
416 }
417 string_prependn (&decl, class.b, class.p - class.b);
418 string_delete (&class);
419 goto do_method_args;
dd3b648e
RP
420 case 'C':
421 /* a const member function */
422 if (!isdigit (p[1]))
423 {
424 string_delete (&decl);
425 return NULL;
426 }
427 p += 1;
428 const_flag = 1;
429 /* fall through */
430 case '0':
431 case '1':
432 case '2':
433 case '3':
434 case '4':
435 case '5':
436 case '6':
437 case '7':
438 case '8':
439 case '9':
440 n = 0;
441 do
442 {
443 n *= 10;
444 n += *p - '0';
445 p += 1;
446 }
447 while (isdigit (*p));
448 if (strlen (p) < n)
449 {
450 string_delete (&decl);
451 return NULL;
452 }
4c53d9ca 453 if (constructor || destructor)
dd3b648e
RP
454 {
455 string_appendn (&decl, p, n);
456 string_append (&decl, "::");
4c53d9ca
DHW
457 if (destructor)
458 string_append(&decl, "~");
dd3b648e
RP
459 string_appendn (&decl, p, n);
460 }
461 else
462 {
463 string_prepend (&decl, "::");
464 string_prependn (&decl, p, n);
465 }
466 p += n;
467#ifndef LONGERNAMES
f536aa39 468 remember_type (premangle, p - premangle, work);
dd3b648e 469#endif
f536aa39 470 do_method_args:
4c53d9ca
DHW
471 if (static_type)
472 {
473 string_append(&decl, p+1);
474 p += strlen(p);
475 success = 1;
476 }
477 else
f536aa39 478 success = do_args (&p, &decl, work);
8f793aa5 479 if (const_flag && PRINT_ARG_TYPES)
dd3b648e
RP
480 string_append (&decl, " const");
481 break;
482 case 'F':
483 p += 1;
f536aa39 484 success = do_args (&p, &decl, work);
dd3b648e 485 break;
4c53d9ca
DHW
486 /* template additions */
487 case 't':
488 p += 1;
489 {
490 int r, i;
4c53d9ca
DHW
491 string tname;
492 string trawname;
493
494 string temp;
495 int need_comma = 0;
496
497 string_init(&tname);
498 string_init(&trawname);
499
500 /* get template name */
501 if (!get_count (&p, &r))
502 return 0;
503 string_appendn (&tname, p, r);
504 string_appendn (&trawname, p, r);
505 string_appendn (&trawname, "", 1);
506 p += r;
507 string_append (&tname, "<");
508 /* get size of template parameter list */
509 if (!get_count (&p, &r))
510 return 0;
511 for (i = 0; i < r; i++)
512 {
513 if (need_comma)
514 string_append (&tname, ", ");
515 /* Z for type parameters */
516 if (*p == 'Z')
517 {
518 p += 1;
519
f536aa39 520 success = do_type (&p, &temp, work);
4c53d9ca
DHW
521 string_appendn (&temp, "", 1);
522 if (success)
523 string_append (&tname, temp.b);
524 string_delete(&temp);
525 if (!success)
526 break;
527 }
528 /* otherwise, value parameter */
529 else
530 {
531 const char *old_p = p;
532 int is_pointer = 0;
533 int is_real = 0;
534 int is_integral = 0;
535 int done = 0;
536
f536aa39 537 success = do_type (&p, &temp, work);
4c53d9ca
DHW
538 string_appendn (&temp, "", 1);
539 if (success)
540 string_append (&tname, temp.b);
541 string_delete(&temp);
542 if (!success)
543 break;
544 string_append (&tname, "=");
545 while (*old_p && !done)
546 {
547 switch (*old_p)
548 {
549 case 'P':
550 case 'R':
551 done = is_pointer = 1;
552 break;
553 case 'C': /* const */
04f27ddc 554 case 'S': /* explicitly signed [char] */
4c53d9ca
DHW
555 case 'U': /* unsigned */
556 case 'V': /* volatile */
557 case 'F': /* function */
558 case 'M': /* member function */
559 case 'O': /* ??? */
560 old_p++;
561 continue;
562 case 'Q': /* repetition of following */
563 case 'T': /* remembered type */
564 abort();
565 break;
566 case 'v': /* void */
567 abort();
568 break;
569 case 'x': /* long long */
570 case 'l': /* long */
571 case 'i': /* int */
572 case 's': /* short */
573 case 'c': /* char */
574 done = is_integral = 1;
575 break;
576 case 'r': /* long double */
577 case 'd': /* double */
578 case 'f': /* float */
579 done = is_real = 1;
580 break;
581 default:
582 abort();
583 }
584 }
585 if (is_integral)
586 {
587 if (*p == 'm')
588 {
589 string_appendn (&tname, "-", 1);
590 p++;
591 }
592 while (isdigit (*p))
593 {
594 string_appendn (&tname, p, 1);
595 p++;
596 }
597 }
598 else if (is_real)
599 {
600 if (*p == 'm')
601 {
602 string_appendn (&tname, "-", 1);
603 p++;
604 }
605 while (isdigit (*p))
606 {
607 string_appendn (&tname, p, 1);
608 p++;
609 }
610 if (*p == '.') /* fraction */
611 {
612 string_appendn (&tname, ".", 1);
613 p++;
614 while (isdigit (*p))
615 {
616 string_appendn (&tname, p, 1);
617 p++;
618 }
619 }
620 if (*p == 'e') /* exponent */
621 {
622 string_appendn (&tname, "e", 1);
623 p++;
624 while (isdigit (*p))
625 {
626 string_appendn (&tname, p, 1);
627 p++;
628 }
629 }
630 }
631 else if (is_pointer)
632 {
633 int symbol_len;
634
635 if (!get_count (&p, &symbol_len))
636 {
637 success = 0;
638 break;
639 }
640 string_appendn (&tname, p, symbol_len);
641 p += symbol_len;
642 }
643 }
644 need_comma = 1;
645 }
646 string_append (&tname, ">::");
647 if (destructor)
648 string_append(&tname, "~");
649 if (constructor || destructor) {
650 string_append (&tname, trawname.b);
651 }
652 string_delete(&trawname);
653
654 if (!success) {
655 string_delete(&tname);
656 return 0;
657 }
658 string_prepend (&decl, tname.b);
659 string_delete(&tname);
660
661 if (static_type)
662 {
663 string_append(&decl, p+1);
664 p += strlen(p);
665 success = 1;
666 }
667 else
f536aa39 668 success = do_args (&p, &decl, work);
4c53d9ca
DHW
669 break;
670 }
dd3b648e
RP
671 }
672
f536aa39
PB
673 for (i = 0; i < work->ntypes; i++)
674 if (work->typevec[i] != NULL)
675 free (work->typevec[i]);
676 if (work->typevec != NULL)
677 free ((char *)work->typevec);
dd3b648e
RP
678
679 if (success)
680 {
681 string_appendn (&decl, "", 1);
682 return decl.b;
683 }
684 else
685 {
686 string_delete (&decl);
687 return NULL;
688 }
689}
690
691static int
692get_count (type, count)
693 const char **type;
694 int *count;
695{
696 if (!isdigit (**type))
697 return 0;
698 *count = **type - '0';
699 *type += 1;
700 /* see flush_repeats in cplus-method.c */
701 if (isdigit (**type))
702 {
703 const char *p = *type;
704 int n = *count;
705 do
706 {
707 n *= 10;
708 n += *p - '0';
709 p += 1;
710 }
711 while (isdigit (*p));
712 if (*p == '_')
713 {
714 *type = p + 1;
715 *count = n;
716 }
717 }
718 return 1;
719}
720
721/* result will be initialised here; it will be freed on failure */
722
723static int
f536aa39 724do_type (type, result, work)
dd3b648e
RP
725 const char **type;
726 string *result;
f536aa39 727 struct work_stuff *work;
dd3b648e
RP
728{
729 int n;
730 int done;
731 int non_empty = 0;
732 int success;
733 string decl;
734 const char *remembered_type;
735
736 string_init (&decl);
737 string_init (result);
738
739 done = 0;
740 success = 1;
741 while (success && !done)
742 {
743 int member;
744 switch (**type)
745 {
55838914
JK
746 case 'Q':
747 n = (*type)[1] - '0';
748 if (n < 0 || n > 9)
749 success = 0;
f536aa39
PB
750 if ((*type)[2] == '_') /* cfront style */
751 *type += 1;
55838914
JK
752 *type += 2;
753 while (n-- > 0)
f536aa39 754 do_type (type, result, work);
55838914
JK
755 break;
756
dd3b648e
RP
757 case 'P':
758 *type += 1;
759 string_prepend (&decl, "*");
760 break;
761
762 case 'R':
763 *type += 1;
764 string_prepend (&decl, "&");
765 break;
766
767 case 'T':
768 *type += 1;
f536aa39 769 if (!get_count (type, &n) || n >= work->ntypes)
dd3b648e
RP
770 success = 0;
771 else
772 {
f536aa39 773 remembered_type = work->typevec[n];
dd3b648e
RP
774 type = &remembered_type;
775 }
776 break;
777
778 case 'F':
779 *type += 1;
780 if (!string_empty (&decl) && decl.b[0] == '*')
781 {
782 string_prepend (&decl, "(");
783 string_append (&decl, ")");
784 }
8f793aa5
FF
785 /* After picking off the function args, we expect to either find the
786 function type (preceded by an '_') or the end of the string. */
787 if (!do_args (type, &decl, work)
788 || (**type != '_' && **type != '\0'))
dd3b648e 789 success = 0;
8f793aa5 790 if (success && (**type == '_'))
dd3b648e
RP
791 *type += 1;
792 break;
793
794 case 'M':
795 case 'O':
796 {
797 int constp = 0;
798 int volatilep = 0;
799
800 member = **type == 'M';
801 *type += 1;
802 if (!isdigit (**type))
803 {
804 success = 0;
805 break;
806 }
807 n = 0;
808 do
809 {
810 n *= 10;
811 n += **type - '0';
812 *type += 1;
813 }
814 while (isdigit (**type));
815 if (strlen (*type) < n)
816 {
817 success = 0;
818 break;
819 }
820 string_append (&decl, ")");
821 string_prepend (&decl, "::");
822 string_prependn (&decl, *type, n);
823 string_prepend (&decl, "(");
824 *type += n;
825 if (member)
826 {
827 if (**type == 'C')
828 {
829 *type += 1;
830 constp = 1;
831 }
832 if (**type == 'V')
833 {
834 *type += 1;
835 volatilep = 1;
836 }
837 if (*(*type)++ != 'F')
838 {
839 success = 0;
840 break;
841 }
842 }
f536aa39 843 if ((member && !do_args (type, &decl, work)) || **type != '_')
dd3b648e
RP
844 {
845 success = 0;
846 break;
847 }
848 *type += 1;
8f793aa5 849 if (! PRINT_ANSI_QUALIFIERS)
dd3b648e
RP
850 break;
851 if (constp)
852 {
853 if (non_empty)
854 string_append (&decl, " ");
855 else
856 non_empty = 1;
857 string_append (&decl, "const");
858 }
859 if (volatilep)
860 {
861 if (non_empty)
862 string_append (&decl, " ");
863 else
864 non_empty = 1;
865 string_append (&decl, "volatile");
866 }
867 break;
868 }
869
870 case 'C':
871 if ((*type)[1] == 'P')
872 {
873 *type += 1;
8f793aa5 874 if (PRINT_ANSI_QUALIFIERS)
dd3b648e
RP
875 {
876 if (!string_empty (&decl))
877 string_prepend (&decl, " ");
878 string_prepend (&decl, "const");
879 }
880 break;
881 }
882
883 /* fall through */
884 default:
885 done = 1;
886 break;
887 }
888 }
889
890 done = 0;
891 non_empty = 0;
892 while (success && !done)
893 {
894 switch (**type)
895 {
896 case 'C':
897 *type += 1;
8f793aa5 898 if (PRINT_ANSI_QUALIFIERS)
dd3b648e
RP
899 {
900 if (non_empty)
901 string_append (result, " ");
902 else
903 non_empty = 1;
904 string_append (result, "const");
905 }
906 break;
907 case 'U':
908 *type += 1;
909 if (non_empty)
910 string_append (result, " ");
911 else
912 non_empty = 1;
913 string_append (result, "unsigned");
914 break;
04f27ddc
PB
915 case 'S': /* signed char only */
916 *type += 1;
917 if (non_empty)
918 string_append (result, " ");
919 else
920 non_empty = 1;
921 string_append (result, "signed");
922 break;
dd3b648e
RP
923 case 'V':
924 *type += 1;
8f793aa5 925 if (PRINT_ANSI_QUALIFIERS)
dd3b648e
RP
926 {
927 if (non_empty)
928 string_append (result, " ");
929 else
930 non_empty = 1;
931 string_append (result, "volatile");
932 }
933 break;
934 default:
935 done = 1;
936 break;
937 }
938 }
939
940 if (success)
941 switch (**type)
942 {
943 case '\0':
944 case '_':
945 break;
946 case 'v':
947 *type += 1;
948 if (non_empty)
949 string_append (result, " ");
950 string_append (result, "void");
951 break;
952 case 'x':
953 *type += 1;
954 if (non_empty)
955 string_append (result, " ");
956 string_append (result, "long long");
957 break;
958 case 'l':
959 *type += 1;
960 if (non_empty)
961 string_append (result, " ");
962 string_append (result, "long");
963 break;
964 case 'i':
965 *type += 1;
966 if (non_empty)
967 string_append (result, " ");
968 string_append (result, "int");
969 break;
970 case 's':
971 *type += 1;
972 if (non_empty)
973 string_append (result, " ");
974 string_append (result, "short");
975 break;
976 case 'c':
977 *type += 1;
978 if (non_empty)
979 string_append (result, " ");
980 string_append (result, "char");
981 break;
982 case 'r':
983 *type += 1;
984 if (non_empty)
985 string_append (result, " ");
986 string_append (result, "long double");
987 break;
988 case 'd':
989 *type += 1;
990 if (non_empty)
991 string_append (result, " ");
992 string_append (result, "double");
993 break;
994 case 'f':
995 *type += 1;
996 if (non_empty)
997 string_append (result, " ");
998 string_append (result, "float");
999 break;
1000 case 'G':
1001 *type += 1;
1002 if (!isdigit (**type))
1003 {
1004 success = 0;
1005 break;
1006 }
1007 /* fall through */
1008 case '0':
1009 case '1':
1010 case '2':
1011 case '3':
1012 case '4':
1013 case '5':
1014 case '6':
1015 case '7':
1016 case '8':
1017 case '9':
1018 n = 0;
1019 do
1020 {
1021 n *= 10;
1022 n += **type - '0';
1023 *type += 1;
1024 }
1025 while (isdigit (**type));
1026 if (strlen (*type) < n)
1027 {
1028 success = 0;
1029 break;
1030 }
1031 if (non_empty)
1032 string_append (result, " ");
1033 string_appendn (result, *type, n);
1034 *type += n;
1035 break;
1036 default:
1037 success = 0;
1038 break;
1039 }
1040
1041 if (success)
1042 {
1043 if (!string_empty (&decl))
1044 {
1045 string_append (result, " ");
1046 string_appends (result, &decl);
1047 }
1048 string_delete (&decl);
1049 return 1;
1050 }
1051 else
1052 {
1053 string_delete (&decl);
1054 string_delete (result);
1055 return 0;
1056 }
1057}
1058
1059/* `result' will be initialised in do_type; it will be freed on failure */
1060
1061static int
f536aa39 1062do_arg (type, result, work)
dd3b648e
RP
1063 const char **type;
1064 string *result;
f536aa39 1065 struct work_stuff *work;
dd3b648e
RP
1066{
1067 const char *start = *type;
1068
f536aa39 1069 if (!do_type (type, result, work))
dd3b648e 1070 return 0;
f536aa39 1071 remember_type (start, *type - start, work);
dd3b648e
RP
1072 return 1;
1073}
1074
1075static void
f536aa39 1076remember_type (start, len, work)
dd3b648e
RP
1077 const char *start;
1078 int len;
f536aa39 1079 struct work_stuff *work;
dd3b648e
RP
1080{
1081 char *tem;
1082
f536aa39 1083 if (work->ntypes >= work->typevec_size)
dd3b648e 1084 {
f536aa39 1085 if (work->typevec_size == 0)
dd3b648e 1086 {
f536aa39
PB
1087 work->typevec_size = 3;
1088 work->typevec = (char **) xmalloc (sizeof (char*)*work->typevec_size);
dd3b648e
RP
1089 }
1090 else
1091 {
f536aa39
PB
1092 work->typevec_size *= 2;
1093 work->typevec = (char **) xrealloc ((char *)work->typevec, sizeof (char*)*work->typevec_size);
dd3b648e
RP
1094 }
1095 }
1096 tem = (char *) xmalloc (len + 1);
1097 memcpy (tem, start, len);
1098 tem[len] = '\0';
f536aa39 1099 work->typevec[work->ntypes++] = tem;
dd3b648e
RP
1100}
1101
1102/* `decl' must be already initialised, usually non-empty;
1103 it won't be freed on failure */
1104
1105static int
f536aa39 1106do_args (type, decl, work)
dd3b648e
RP
1107 const char **type;
1108 string *decl;
f536aa39 1109 struct work_stuff *work;
dd3b648e
RP
1110{
1111 string arg;
1112 int need_comma = 0;
1113
8f793aa5 1114 if (PRINT_ARG_TYPES)
dd3b648e
RP
1115 string_append (decl, "(");
1116
1117 while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v')
1118 {
1119 if (**type == 'N')
1120 {
1121 int r;
1122 int t;
1123 *type += 1;
f536aa39 1124 if (!get_count (type, &r) || !get_count (type, &t) || t >= work->ntypes)
dd3b648e
RP
1125 return 0;
1126 while (--r >= 0)
1127 {
f536aa39 1128 const char *tem = work->typevec[t];
8f793aa5 1129 if (need_comma && PRINT_ARG_TYPES)
dd3b648e 1130 string_append (decl, ", ");
f536aa39 1131 if (!do_arg (&tem, &arg, work))
dd3b648e 1132 return 0;
8f793aa5 1133 if (PRINT_ARG_TYPES)
dd3b648e
RP
1134 string_appends (decl, &arg);
1135 string_delete (&arg);
1136 need_comma = 1;
1137 }
1138 }
1139 else
1140 {
8f793aa5 1141 if (need_comma & PRINT_ARG_TYPES)
dd3b648e 1142 string_append (decl, ", ");
f536aa39 1143 if (!do_arg (type, &arg, work))
dd3b648e 1144 return 0;
8f793aa5 1145 if (PRINT_ARG_TYPES)
dd3b648e
RP
1146 string_appends (decl, &arg);
1147 string_delete (&arg);
1148 need_comma = 1;
1149 }
1150 }
1151
1152 if (**type == 'v')
1153 *type += 1;
1154 else if (**type == 'e')
1155 {
1156 *type += 1;
8f793aa5 1157 if (PRINT_ARG_TYPES)
dd3b648e
RP
1158 {
1159 if (need_comma)
1160 string_append (decl, ",");
1161 string_append (decl, "...");
1162 }
1163 }
1164
8f793aa5 1165 if (PRINT_ARG_TYPES)
dd3b648e
RP
1166 string_append (decl, ")");
1167 return 1;
1168}
1169
1170static void
f536aa39 1171munge_function_name (name, work)
dd3b648e 1172 string *name;
f536aa39 1173 struct work_stuff *work;
dd3b648e 1174{
572acbbe
MT
1175 if (string_empty (name))
1176 return;
1177
1178 if (name->p - name->b >= 3
f88e7af8 1179 && name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == CPLUS_MARKER)
dd3b648e
RP
1180 {
1181 int i;
1182 /* see if it's an assignment expression */
1183 if (name->p - name->b >= 10 /* op$assign_ */
1184 && memcmp (name->b + 3, "assign_", 7) == 0)
1185 {
1186 for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
1187 {
1188 int len = name->p - name->b - 10;
1189 if (strlen (optable[i].in) == len
1190 && memcmp (optable[i].in, name->b + 10, len) == 0)
1191 {
1192 string_clear (name);
1193 string_append (name, "operator");
1194 string_append (name, optable[i].out);
1195 string_append (name, "=");
1196 return;
1197 }
1198 }
1199 }
1200 else
1201 {
1202 for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
1203 {
1204 int len = name->p - name->b - 3;
1205 if (strlen (optable[i].in) == len
1206 && memcmp (optable[i].in, name->b + 3, len) == 0)
1207 {
1208 string_clear (name);
1209 string_append (name, "operator");
1210 string_append (name, optable[i].out);
1211 return;
1212 }
1213 }
1214 }
1215 return;
1216 }
572acbbe 1217 else if (name->p - name->b >= 5 && memcmp (name->b, "type$", 5) == 0)
dd3b648e
RP
1218 {
1219 /* type conversion operator */
1220 string type;
1221 const char *tem = name->b + 5;
f536aa39 1222 if (do_type (&tem, &type, work))
dd3b648e
RP
1223 {
1224 string_clear (name);
1225 string_append (name, "operator ");
1226 string_appends (name, &type);
1227 string_delete (&type);
1228 return;
1229 }
1230 }
572acbbe
MT
1231 /* ANSI. */
1232 else if (name->b[2] == 'o' && name->b[3] == 'p')
1233 {
1234 /* type conversion operator. */
1235 string type;
1236 const char *tem = name->b + 4;
f536aa39 1237 if (do_type (&tem, &type, work))
572acbbe
MT
1238 {
1239 string_clear (name);
1240 string_append (name, "operator ");
1241 string_appends (name, &type);
1242 string_delete (&type);
1243 return;
1244 }
1245 }
1246 else if (name->b[0] == '_' && name->b[1] == '_'
1247 && name->b[2] >= 'a' && name->b[2] <= 'z'
1248 && name->b[3] >= 'a' && name->b[3] <= 'z')
1249 {
1250 int i;
1251
1252 if (name->b[4] == '\0')
1253 {
1254 /* Operator. */
1255 for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
1256 {
1257 if (strlen (optable[i].in) == 2
1258 && memcmp (optable[i].in, name->b + 2, 2) == 0)
1259 {
1260 string_clear (name);
1261 string_append (name, "operator");
1262 string_append (name, optable[i].out);
1263 return;
1264 }
1265 }
1266 }
1267 else
1268 {
1269 if (name->b[2] != 'a' || name->b[5] != '\0')
1270 return;
1271 /* Assignment. */
1272 for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
1273 {
1274 if (strlen (optable[i].in) == 3
1275 && memcmp (optable[i].in, name->b + 2, 3) == 0)
1276 {
1277 string_clear (name);
1278 string_append (name, "operator");
1279 string_append (name, optable[i].out);
1280 return;
1281 }
1282 }
1283 }
1284 }
dd3b648e
RP
1285}
1286
1287/* a mini string-handling package */
1288
1289static void
1290string_need (s, n)
1291 string *s;
1292 int n;
1293{
1294 if (s->b == NULL)
1295 {
1296 if (n < 32)
1297 n = 32;
1298 s->p = s->b = (char *) xmalloc (n);
1299 s->e = s->b + n;
1300 }
1301 else if (s->e - s->p < n)
1302 {
1303 int tem = s->p - s->b;
1304 n += tem;
1305 n *= 2;
1306 s->b = (char *) xrealloc (s->b, n);
1307 s->p = s->b + tem;
1308 s->e = s->b + n;
1309 }
1310}
1311
1312static void
1313string_delete (s)
1314 string *s;
1315{
1316 if (s->b != NULL)
1317 {
1318 free (s->b);
1319 s->b = s->e = s->p = NULL;
1320 }
1321}
1322
1323static void
1324string_init (s)
1325 string *s;
1326{
1327 s->b = s->p = s->e = NULL;
1328}
1329
1330static void
1331string_clear (s)
1332 string *s;
1333{
1334 s->p = s->b;
1335}
1336
1337static int
1338string_empty (s)
1339 string *s;
1340{
1341 return s->b == s->p;
1342}
1343
1344static void
1345string_append (p, s)
1346 string *p;
1347 const char *s;
1348{
1349 int n;
1350 if (s == NULL || *s == '\0')
1351 return;
1352 n = strlen (s);
1353 string_need (p, n);
1354 memcpy (p->p, s, n);
1355 p->p += n;
1356}
1357
1358static void
1359string_appends (p, s)
1360 string *p, *s;
1361{
1362 int n;
1363 if (s->b == s->p)
1364 return;
1365 n = s->p - s->b;
1366 string_need (p, n);
1367 memcpy (p->p, s->b, n);
1368 p->p += n;
1369}
1370
1371static void
1372string_appendn (p, s, n)
1373 string *p;
1374 const char *s;
1375 int n;
1376{
1377 if (n == 0)
1378 return;
1379 string_need (p, n);
1380 memcpy (p->p, s, n);
1381 p->p += n;
1382}
1383
1384static void
1385string_prepend (p, s)
1386 string *p;
1387 const char *s;
1388{
1389 if (s == NULL || *s == '\0')
1390 return;
1391 string_prependn (p, s, strlen (s));
1392}
1393
1394#if 0
1395static void
1396string_prepends (p, s)
1397 string *p, *s;
1398{
1399 if (s->b == s->p)
1400 return;
1401 string_prependn (p, s->b, s->p - s->b);
1402}
1403#endif
1404
1405static void
1406string_prependn (p, s, n)
1407 string *p;
1408 const char *s;
1409 int n;
1410{
1411 char *q;
1412
1413 if (n == 0)
1414 return;
1415 string_need (p, n);
1416 for (q = p->p - 1; q >= p->b; q--)
1417 q[n] = q[0];
1418 memcpy (p->b, s, n);
1419 p->p += n;
1420}
This page took 0.215272 seconds and 4 git commands to generate.