~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to binutils/libiberty/cp-demangle.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Demangler for IA64 / g++ V3 ABI.
 
2
   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
 
3
   Written by Alex Samuel <samuel@codesourcery.com>. 
 
4
 
 
5
   This file is part of GNU CC.
 
6
 
 
7
   This program is free software; you can redistribute it and/or modify
 
8
   it under the terms of the GNU General Public License as published by
 
9
   the Free Software Foundation; either version 2 of the License, or
 
10
   (at your option) any later version.
 
11
 
 
12
   In addition to the permissions in the GNU General Public License, the
 
13
   Free Software Foundation gives you unlimited permission to link the
 
14
   compiled version of this file into combinations with other programs,
 
15
   and to distribute those combinations without any restriction coming
 
16
   from the use of this file.  (The General Public License restrictions
 
17
   do apply in other respects; for example, they cover modification of
 
18
   the file, and distribution when not linked into a combined
 
19
   executable.)
 
20
 
 
21
   This program is distributed in the hope that it will be useful,
 
22
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
23
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
24
   GNU General Public License for more details.
 
25
 
 
26
   You should have received a copy of the GNU General Public License
 
27
   along with this program; if not, write to the Free Software
 
28
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
 
29
*/
 
30
 
 
31
/* This file implements demangling of C++ names mangled according to
 
32
   the IA64 / g++ V3 ABI.  Use the cp_demangle function to
 
33
   demangle a mangled name, or compile with the preprocessor macro
 
34
   STANDALONE_DEMANGLER defined to create a demangling filter
 
35
   executable (functionally similar to c++filt, but includes this
 
36
   demangler only).  */
 
37
 
 
38
#ifdef HAVE_CONFIG_H
 
39
#include "config.h"
 
40
#endif
 
41
 
 
42
#include <sys/types.h>
 
43
 
 
44
#ifdef HAVE_STDLIB_H
 
45
#include <stdlib.h>
 
46
#endif
 
47
 
 
48
#include <stdio.h>
 
49
 
 
50
#ifdef HAVE_STRING_H
 
51
#include <string.h>
 
52
#endif
 
53
 
 
54
#include <ctype.h>
 
55
 
 
56
#include "ansidecl.h"
 
57
#include "libiberty.h"
 
58
#include "dyn-string.h"
 
59
#include "demangle.h"
 
60
 
 
61
/* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
 
62
   and other debugging output, will be generated. */
 
63
#ifdef CP_DEMANGLE_DEBUG
 
64
#define DEMANGLE_TRACE(PRODUCTION, DM)                                  \
 
65
  fprintf (stderr, " -> %-24s at position %3d\n",                       \
 
66
           (PRODUCTION), current_position (DM));
 
67
#else
 
68
#define DEMANGLE_TRACE(PRODUCTION, DM)
 
69
#endif
 
70
 
 
71
/* Don't include <ctype.h>, to prevent additional unresolved symbols
 
72
   from being dragged into the C++ runtime library.  */
 
73
#define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9')
 
74
#define IS_ALPHA(CHAR)                                                  \
 
75
  (((CHAR) >= 'a' && (CHAR) <= 'z')                                     \
 
76
   || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
 
77
 
 
78
/* The prefix prepended by GCC to an identifier represnting the
 
79
   anonymous namespace.  */
 
80
#define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
 
81
 
 
82
/* Character(s) to use for namespace separation in demangled output */
 
83
#define NAMESPACE_SEPARATOR (dm->style == DMGL_JAVA ? "." : "::")
 
84
 
 
85
/* If flag_verbose is zero, some simplifications will be made to the
 
86
   output to make it easier to read and supress details that are
 
87
   generally not of interest to the average C++ programmer.
 
88
   Otherwise, the demangled representation will attempt to convey as
 
89
   much information as the mangled form.  */
 
90
static int flag_verbose;
 
91
 
 
92
/* If flag_strict is non-zero, demangle strictly according to the
 
93
   specification -- don't demangle special g++ manglings.  */
 
94
static int flag_strict;
 
95
 
 
96
/* String_list_t is an extended form of dyn_string_t which provides a
 
97
   link field and a caret position for additions to the string.  A
 
98
   string_list_t may safely be cast to and used as a dyn_string_t.  */
 
99
 
 
100
struct string_list_def
 
101
{
 
102
  /* The dyn_string; must be first.  */
 
103
  struct dyn_string string;
 
104
 
 
105
  /* The position at which additional text is added to this string
 
106
     (using the result_add* macros).  This value is an offset from the
 
107
     end of the string, not the beginning (and should be
 
108
     non-positive).  */
 
109
  int caret_position;
 
110
 
 
111
  /* The next string in the list.  */
 
112
  struct string_list_def *next;
 
113
};
 
114
 
 
115
typedef struct string_list_def *string_list_t;
 
116
 
 
117
/* Data structure representing a potential substitution.  */
 
118
 
 
119
struct substitution_def
 
120
{
 
121
  /* The demangled text of the substitution.  */
 
122
  dyn_string_t text;
 
123
 
 
124
  /* Whether this substitution represents a template item.  */
 
125
  int template_p : 1;
 
126
};
 
127
 
 
128
/* Data structure representing a template argument list.  */
 
129
 
 
130
struct template_arg_list_def
 
131
{
 
132
  /* The next (lower) template argument list in the stack of currently
 
133
     active template arguments.  */
 
134
  struct template_arg_list_def *next;
 
135
 
 
136
  /* The first element in the list of template arguments in
 
137
     left-to-right order.  */
 
138
  string_list_t first_argument;
 
139
 
 
140
  /* The last element in the arguments lists.  */
 
141
  string_list_t last_argument;
 
142
};
 
143
 
 
144
typedef struct template_arg_list_def *template_arg_list_t;
 
145
 
 
146
/* Data structure to maintain the state of the current demangling.  */
 
147
 
 
148
struct demangling_def
 
149
{
 
150
  /* The full mangled name being mangled.  */
 
151
  const char *name;
 
152
 
 
153
  /* Pointer into name at the current position.  */
 
154
  const char *next;
 
155
 
 
156
  /* Stack for strings containing demangled result generated so far.
 
157
     Text is emitted to the topmost (first) string.  */
 
158
  string_list_t result;
 
159
 
 
160
  /* The number of presently available substitutions.  */
 
161
  int num_substitutions;
 
162
 
 
163
  /* The allocated size of the substitutions array.  */
 
164
  int substitutions_allocated;
 
165
 
 
166
  /* An array of available substitutions.  The number of elements in
 
167
     the array is given by num_substitions, and the allocated array
 
168
     size in substitutions_size.  
 
169
 
 
170
     The most recent substition is at the end, so
 
171
 
 
172
       - `S_'  corresponds to substititutions[num_substitutions - 1] 
 
173
       - `S0_' corresponds to substititutions[num_substitutions - 2]
 
174
 
 
175
     etc. */
 
176
  struct substitution_def *substitutions;
 
177
 
 
178
  /* The stack of template argument lists.  */
 
179
  template_arg_list_t template_arg_lists;
 
180
 
 
181
  /* The most recently demangled source-name.  */
 
182
  dyn_string_t last_source_name;
 
183
  
 
184
  /* Language style to use for demangled output. */
 
185
  int style;
 
186
 
 
187
  /* Set to non-zero iff this name is a constructor.  The actual value
 
188
     indicates what sort of constructor this is; see demangle.h.  */
 
189
  enum gnu_v3_ctor_kinds is_constructor;
 
190
 
 
191
  /* Set to non-zero iff this name is a destructor.  The actual value
 
192
     indicates what sort of destructor this is; see demangle.h.  */
 
193
  enum gnu_v3_dtor_kinds is_destructor;
 
194
 
 
195
};
 
196
 
 
197
typedef struct demangling_def *demangling_t;
 
198
 
 
199
/* This type is the standard return code from most functions.  Values
 
200
   other than STATUS_OK contain descriptive messages.  */
 
201
typedef const char *status_t;
 
202
 
 
203
/* Special values that can be used as a status_t.  */
 
204
#define STATUS_OK                       NULL
 
205
#define STATUS_ERROR                    "Error."
 
206
#define STATUS_UNIMPLEMENTED            "Unimplemented."
 
207
#define STATUS_INTERNAL_ERROR           "Internal error."
 
208
 
 
209
/* This status code indicates a failure in malloc or realloc.  */
 
210
static const char *const status_allocation_failed = "Allocation failed.";
 
211
#define STATUS_ALLOCATION_FAILED        status_allocation_failed
 
212
 
 
213
/* Non-zero if STATUS indicates that no error has occurred.  */
 
214
#define STATUS_NO_ERROR(STATUS)         ((STATUS) == STATUS_OK)
 
215
 
 
216
/* Evaluate EXPR, which must produce a status_t.  If the status code
 
217
   indicates an error, return from the current function with that
 
218
   status code.  */
 
219
#define RETURN_IF_ERROR(EXPR)                                           \
 
220
  do                                                                    \
 
221
    {                                                                   \
 
222
      status_t s = EXPR;                                                \
 
223
      if (!STATUS_NO_ERROR (s))                                         \
 
224
        return s;                                                       \
 
225
    }                                                                   \
 
226
  while (0)
 
227
 
 
228
static status_t int_to_dyn_string 
 
229
  PARAMS ((int, dyn_string_t));
 
230
static string_list_t string_list_new
 
231
  PARAMS ((int));
 
232
static void string_list_delete
 
233
  PARAMS ((string_list_t));
 
234
static status_t result_add_separated_char
 
235
  PARAMS ((demangling_t, int));
 
236
static status_t result_push
 
237
  PARAMS ((demangling_t));
 
238
static string_list_t result_pop
 
239
  PARAMS ((demangling_t));
 
240
static int substitution_start
 
241
  PARAMS ((demangling_t));
 
242
static status_t substitution_add
 
243
  PARAMS ((demangling_t, int, int));
 
244
static dyn_string_t substitution_get
 
245
  PARAMS ((demangling_t, int, int *));
 
246
#ifdef CP_DEMANGLE_DEBUG
 
247
static void substitutions_print 
 
248
  PARAMS ((demangling_t, FILE *));
 
249
#endif
 
250
static template_arg_list_t template_arg_list_new
 
251
  PARAMS ((void));
 
252
static void template_arg_list_delete
 
253
  PARAMS ((template_arg_list_t));
 
254
static void template_arg_list_add_arg 
 
255
  PARAMS ((template_arg_list_t, string_list_t));
 
256
static string_list_t template_arg_list_get_arg
 
257
  PARAMS ((template_arg_list_t, int));
 
258
static void push_template_arg_list
 
259
  PARAMS ((demangling_t, template_arg_list_t));
 
260
static void pop_to_template_arg_list
 
261
  PARAMS ((demangling_t, template_arg_list_t));
 
262
#ifdef CP_DEMANGLE_DEBUG
 
263
static void template_arg_list_print
 
264
  PARAMS ((template_arg_list_t, FILE *));
 
265
#endif
 
266
static template_arg_list_t current_template_arg_list
 
267
  PARAMS ((demangling_t));
 
268
static demangling_t demangling_new
 
269
  PARAMS ((const char *, int));
 
270
static void demangling_delete 
 
271
  PARAMS ((demangling_t));
 
272
 
 
273
/* The last character of DS.  Warning: DS is evaluated twice.  */
 
274
#define dyn_string_last_char(DS)                                        \
 
275
  (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
 
276
 
 
277
/* Append a space character (` ') to DS if it does not already end
 
278
   with one.  Evaluates to 1 on success, or 0 on allocation failure.  */
 
279
#define dyn_string_append_space(DS)                                     \
 
280
      ((dyn_string_length (DS) > 0                                      \
 
281
        && dyn_string_last_char (DS) != ' ')                            \
 
282
       ? dyn_string_append_char ((DS), ' ')                             \
 
283
       : 1)
 
284
 
 
285
/* Returns the index of the current position in the mangled name.  */
 
286
#define current_position(DM)    ((DM)->next - (DM)->name)
 
287
 
 
288
/* Returns the character at the current position of the mangled name.  */
 
289
#define peek_char(DM)           (*((DM)->next))
 
290
 
 
291
/* Returns the character one past the current position of the mangled
 
292
   name.  */
 
293
#define peek_char_next(DM)                                              \
 
294
  (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
 
295
 
 
296
/* Returns the character at the current position, and advances the
 
297
   current position to the next character.  */
 
298
#define next_char(DM)           (*((DM)->next)++)
 
299
 
 
300
/* Returns non-zero if the current position is the end of the mangled
 
301
   name, i.e. one past the last character.  */
 
302
#define end_of_name_p(DM)       (peek_char (DM) == '\0')
 
303
 
 
304
/* Advances the current position by one character.  */
 
305
#define advance_char(DM)        (++(DM)->next)
 
306
 
 
307
/* Returns the string containing the current demangled result.  */
 
308
#define result_string(DM)       (&(DM)->result->string)
 
309
 
 
310
/* Returns the position at which new text is inserted into the
 
311
   demangled result.  */
 
312
#define result_caret_pos(DM)                                            \
 
313
  (result_length (DM) +                                                 \
 
314
   ((string_list_t) result_string (DM))->caret_position)
 
315
 
 
316
/* Adds a dyn_string_t to the demangled result.  */
 
317
#define result_add_string(DM, STRING)                                   \
 
318
  (dyn_string_insert (&(DM)->result->string,                            \
 
319
                      result_caret_pos (DM), (STRING))                  \
 
320
   ? STATUS_OK : STATUS_ALLOCATION_FAILED)
 
321
 
 
322
/* Adds NUL-terminated string CSTR to the demangled result.    */
 
323
#define result_add(DM, CSTR)                                            \
 
324
  (dyn_string_insert_cstr (&(DM)->result->string,                       \
 
325
                           result_caret_pos (DM), (CSTR))               \
 
326
   ? STATUS_OK : STATUS_ALLOCATION_FAILED)
 
327
 
 
328
/* Adds character CHAR to the demangled result.  */
 
329
#define result_add_char(DM, CHAR)                                       \
 
330
  (dyn_string_insert_char (&(DM)->result->string,                       \
 
331
                           result_caret_pos (DM), (CHAR))               \
 
332
   ? STATUS_OK : STATUS_ALLOCATION_FAILED)
 
333
 
 
334
/* Inserts a dyn_string_t to the demangled result at position POS.  */
 
335
#define result_insert_string(DM, POS, STRING)                           \
 
336
  (dyn_string_insert (&(DM)->result->string, (POS), (STRING))           \
 
337
   ? STATUS_OK : STATUS_ALLOCATION_FAILED)
 
338
 
 
339
/* Inserts NUL-terminated string CSTR to the demangled result at
 
340
   position POS.  */
 
341
#define result_insert(DM, POS, CSTR)                                    \
 
342
  (dyn_string_insert_cstr (&(DM)->result->string, (POS), (CSTR))        \
 
343
   ? STATUS_OK : STATUS_ALLOCATION_FAILED)
 
344
 
 
345
/* Inserts character CHAR to the demangled result at position POS.  */
 
346
#define result_insert_char(DM, POS, CHAR)                               \
 
347
  (dyn_string_insert_char (&(DM)->result->string, (POS), (CHAR))        \
 
348
   ? STATUS_OK : STATUS_ALLOCATION_FAILED)
 
349
 
 
350
/* The length of the current demangled result.  */
 
351
#define result_length(DM)                                               \
 
352
  dyn_string_length (&(DM)->result->string)
 
353
 
 
354
/* Appends a (less-than, greater-than) character to the result in DM
 
355
   to (open, close) a template argument or parameter list.  Appends a
 
356
   space first if necessary to prevent spurious elision of angle
 
357
   brackets with the previous character.  */
 
358
#define result_open_template_list(DM) result_add_separated_char(DM, '<')
 
359
#define result_close_template_list(DM) result_add_separated_char(DM, '>')
 
360
 
 
361
/* Appends a base 10 representation of VALUE to DS.  STATUS_OK on
 
362
   success.  On failure, deletes DS and returns an error code.  */
 
363
 
 
364
static status_t
 
365
int_to_dyn_string (value, ds)
 
366
     int value;
 
367
     dyn_string_t ds;
 
368
{
 
369
  int i;
 
370
  int mask = 1;
 
371
 
 
372
  /* Handle zero up front.  */
 
373
  if (value == 0)
 
374
    {
 
375
      if (!dyn_string_append_char (ds, '0'))
 
376
        return STATUS_ALLOCATION_FAILED;
 
377
      return STATUS_OK;
 
378
    }
 
379
 
 
380
  /* For negative numbers, emit a minus sign.  */
 
381
  if (value < 0)
 
382
    {
 
383
      if (!dyn_string_append_char (ds, '-'))
 
384
        return STATUS_ALLOCATION_FAILED;
 
385
      value = -value;
 
386
    }
 
387
  
 
388
  /* Find the power of 10 of the first digit.  */
 
389
  i = value;
 
390
  while (i > 9)
 
391
    {
 
392
      mask *= 10;
 
393
      i /= 10;
 
394
    }
 
395
 
 
396
  /* Write the digits.  */
 
397
  while (mask > 0)
 
398
    {
 
399
      int digit = value / mask;
 
400
 
 
401
      if (!dyn_string_append_char (ds, '0' + digit))
 
402
        return STATUS_ALLOCATION_FAILED;
 
403
 
 
404
      value -= digit * mask;
 
405
      mask /= 10;
 
406
    }
 
407
 
 
408
  return STATUS_OK;
 
409
}
 
410
 
 
411
/* Creates a new string list node.  The contents of the string are
 
412
   empty, but the initial buffer allocation is LENGTH.  The string
 
413
   list node should be deleted with string_list_delete.  Returns NULL
 
414
   if allocation fails.  */
 
415
 
 
416
static string_list_t 
 
417
string_list_new (length)
 
418
     int length;
 
419
{
 
420
  string_list_t s = (string_list_t) malloc (sizeof (struct string_list_def));
 
421
  s->caret_position = 0;
 
422
  if (s == NULL)
 
423
    return NULL;
 
424
  if (!dyn_string_init ((dyn_string_t) s, length))
 
425
    return NULL;
 
426
  return s;
 
427
}  
 
428
 
 
429
/* Deletes the entire string list starting at NODE.  */
 
430
 
 
431
static void
 
432
string_list_delete (node)
 
433
     string_list_t node;
 
434
{
 
435
  while (node != NULL)
 
436
    {
 
437
      string_list_t next = node->next;
 
438
      dyn_string_delete ((dyn_string_t) node);
 
439
      node = next;
 
440
    }
 
441
}
 
442
 
 
443
/* Appends CHARACTER to the demangled result.  If the current trailing
 
444
   character of the result is CHARACTER, a space is inserted first.  */
 
445
 
 
446
static status_t
 
447
result_add_separated_char (dm, character)
 
448
     demangling_t dm;
 
449
     int character;
 
450
{
 
451
  char *result = dyn_string_buf (result_string (dm));
 
452
  int caret_pos = result_caret_pos (dm);
 
453
 
 
454
  /* Add a space if the last character is already the character we
 
455
     want to add.  */
 
456
  if (caret_pos > 0 && result[caret_pos - 1] == character)
 
457
    RETURN_IF_ERROR (result_add_char (dm, ' '));
 
458
  /* Add the character.  */
 
459
  RETURN_IF_ERROR (result_add_char (dm, character));
 
460
 
 
461
  return STATUS_OK;
 
462
}
 
463
 
 
464
/* Allocates and pushes a new string onto the demangled results stack
 
465
   for DM.  Subsequent demangling with DM will emit to the new string.
 
466
   Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
 
467
   allocation failure.  */
 
468
 
 
469
static status_t
 
470
result_push (dm)
 
471
     demangling_t dm;
 
472
{
 
473
  string_list_t new_string = string_list_new (0);
 
474
  if (new_string == NULL)
 
475
    /* Allocation failed.  */
 
476
    return STATUS_ALLOCATION_FAILED;
 
477
 
 
478
  /* Link the new string to the front of the list of result strings.  */
 
479
  new_string->next = (string_list_t) dm->result;
 
480
  dm->result = new_string;
 
481
  return STATUS_OK;
 
482
}
 
483
 
 
484
/* Removes and returns the topmost element on the demangled results
 
485
   stack for DM.  The caller assumes ownership for the returned
 
486
   string.  */
 
487
 
 
488
static string_list_t
 
489
result_pop (dm)
 
490
     demangling_t dm;
 
491
{
 
492
  string_list_t top = dm->result;
 
493
  dm->result = top->next;
 
494
  return top;
 
495
}
 
496
 
 
497
/* Returns the current value of the caret for the result string.  The
 
498
   value is an offet from the end of the result string.  */
 
499
 
 
500
static int
 
501
result_get_caret (dm)
 
502
     demangling_t dm;
 
503
{
 
504
  return ((string_list_t) result_string (dm))->caret_position;
 
505
}
 
506
 
 
507
/* Sets the value of the caret for the result string, counted as an
 
508
   offet from the end of the result string.  */
 
509
 
 
510
static void
 
511
result_set_caret (dm, position)
 
512
     demangling_t dm;
 
513
     int position;
 
514
{
 
515
  ((string_list_t) result_string (dm))->caret_position = position;
 
516
}
 
517
 
 
518
/* Shifts the position of the next addition to the result by
 
519
   POSITION_OFFSET.  A negative value shifts the caret to the left.  */
 
520
 
 
521
static void
 
522
result_shift_caret (dm, position_offset)
 
523
     demangling_t dm;
 
524
     int position_offset;
 
525
{
 
526
  ((string_list_t) result_string (dm))->caret_position += position_offset;
 
527
}
 
528
 
 
529
/* Returns non-zero if the character that comes right before the place
 
530
   where text will be added to the result is a space.  In this case,
 
531
   the caller should supress adding another space.  */
 
532
 
 
533
static int
 
534
result_previous_char_is_space (dm)
 
535
     demangling_t dm;
 
536
{
 
537
  char *result = dyn_string_buf (result_string (dm));
 
538
  int pos = result_caret_pos (dm);
 
539
  return pos > 0 && result[pos - 1] == ' ';
 
540
}
 
541
 
 
542
/* Returns the start position of a fragment of the demangled result
 
543
   that will be a substitution candidate.  Should be called at the
 
544
   start of productions that can add substitutions.  */
 
545
 
 
546
static int
 
547
substitution_start (dm)
 
548
     demangling_t dm;
 
549
{
 
550
  return result_caret_pos (dm);
 
551
}
 
552
 
 
553
/* Adds the suffix of the current demangled result of DM starting at
 
554
   START_POSITION as a potential substitution.  If TEMPLATE_P is
 
555
   non-zero, this potential substitution is a template-id.  */
 
556
 
 
557
static status_t
 
558
substitution_add (dm, start_position, template_p)
 
559
     demangling_t dm;
 
560
     int start_position;
 
561
     int template_p;
 
562
{
 
563
  dyn_string_t result = result_string (dm);
 
564
  dyn_string_t substitution = dyn_string_new (0);
 
565
  int i;
 
566
 
 
567
  if (substitution == NULL)
 
568
    return STATUS_ALLOCATION_FAILED;
 
569
 
 
570
  /* Extract the substring of the current demangling result that
 
571
     represents the subsitution candidate.  */
 
572
  if (!dyn_string_substring (substitution, 
 
573
                             result, start_position, result_caret_pos (dm)))
 
574
    {
 
575
      dyn_string_delete (substitution);
 
576
      return STATUS_ALLOCATION_FAILED;
 
577
    }
 
578
 
 
579
  /* If there's no room for the new entry, grow the array.  */
 
580
  if (dm->substitutions_allocated == dm->num_substitutions)
 
581
    {
 
582
      size_t new_array_size;
 
583
      if (dm->substitutions_allocated > 0)
 
584
        dm->substitutions_allocated *= 2;
 
585
      else
 
586
        dm->substitutions_allocated = 2;
 
587
      new_array_size = 
 
588
        sizeof (struct substitution_def) * dm->substitutions_allocated;
 
589
 
 
590
      dm->substitutions = (struct substitution_def *)
 
591
        realloc (dm->substitutions, new_array_size);
 
592
      if (dm->substitutions == NULL)
 
593
        /* Realloc failed.  */
 
594
        {
 
595
          dyn_string_delete (substitution);
 
596
          return STATUS_ALLOCATION_FAILED;
 
597
        }
 
598
    }
 
599
 
 
600
  /* Add the substitution to the array.  */
 
601
  i = dm->num_substitutions++;
 
602
  dm->substitutions[i].text = substitution;
 
603
  dm->substitutions[i].template_p = template_p;
 
604
 
 
605
#ifdef CP_DEMANGLE_DEBUG
 
606
  substitutions_print (dm, stderr);
 
607
#endif
 
608
 
 
609
  return STATUS_OK;
 
610
}
 
611
 
 
612
/* Returns the Nth-most-recent substitution.  Sets *TEMPLATE_P to
 
613
   non-zero if the substitution is a template-id, zero otherwise.  
 
614
   N is numbered from zero.  DM retains ownership of the returned
 
615
   string.  If N is negative, or equal to or greater than the current
 
616
   number of substitution candidates, returns NULL.  */
 
617
 
 
618
static dyn_string_t
 
619
substitution_get (dm, n, template_p)
 
620
     demangling_t dm;
 
621
     int n;
 
622
     int *template_p;
 
623
{
 
624
  struct substitution_def *sub;
 
625
 
 
626
  /* Make sure N is in the valid range.  */
 
627
  if (n < 0 || n >= dm->num_substitutions)
 
628
    return NULL;
 
629
 
 
630
  sub = &(dm->substitutions[n]);
 
631
  *template_p = sub->template_p;
 
632
  return sub->text;
 
633
}
 
634
 
 
635
#ifdef CP_DEMANGLE_DEBUG
 
636
/* Debugging routine to print the current substitutions to FP.  */
 
637
 
 
638
static void
 
639
substitutions_print (dm, fp)
 
640
     demangling_t dm;
 
641
     FILE *fp;
 
642
{
 
643
  int seq_id;
 
644
  int num = dm->num_substitutions;
 
645
 
 
646
  fprintf (fp, "SUBSTITUTIONS:\n");
 
647
  for (seq_id = -1; seq_id < num - 1; ++seq_id)
 
648
    {
 
649
      int template_p;
 
650
      dyn_string_t text = substitution_get (dm, seq_id + 1, &template_p);
 
651
 
 
652
      if (seq_id == -1)
 
653
        fprintf (fp, " S_ ");
 
654
      else
 
655
        fprintf (fp, " S%d_", seq_id);
 
656
      fprintf (fp, " %c: %s\n", template_p ? '*' : ' ', dyn_string_buf (text));
 
657
    }
 
658
}
 
659
 
 
660
#endif /* CP_DEMANGLE_DEBUG */
 
661
 
 
662
/* Creates a new template argument list.  Returns NULL if allocation
 
663
   fails.  */
 
664
 
 
665
static template_arg_list_t
 
666
template_arg_list_new ()
 
667
{
 
668
  template_arg_list_t new_list =
 
669
    (template_arg_list_t) malloc (sizeof (struct template_arg_list_def));
 
670
  if (new_list == NULL)
 
671
    return NULL;
 
672
  /* Initialize the new list to have no arguments.  */
 
673
  new_list->first_argument = NULL;
 
674
  new_list->last_argument = NULL;
 
675
  /* Return the new list.  */
 
676
  return new_list;
 
677
}
 
678
 
 
679
/* Deletes a template argument list and the template arguments it
 
680
   contains.  */
 
681
 
 
682
static void
 
683
template_arg_list_delete (list)
 
684
     template_arg_list_t list;
 
685
{
 
686
  /* If there are any arguments on LIST, delete them.  */
 
687
  if (list->first_argument != NULL)
 
688
    string_list_delete (list->first_argument);
 
689
  /* Delete LIST.  */
 
690
  free (list);
 
691
}
 
692
 
 
693
/* Adds ARG to the template argument list ARG_LIST.  */
 
694
 
 
695
static void 
 
696
template_arg_list_add_arg (arg_list, arg)
 
697
     template_arg_list_t arg_list;
 
698
     string_list_t arg;
 
699
{
 
700
  if (arg_list->first_argument == NULL)
 
701
    /* If there were no arguments before, ARG is the first one.  */
 
702
    arg_list->first_argument = arg;
 
703
  else
 
704
    /* Make ARG the last argument on the list.  */
 
705
    arg_list->last_argument->next = arg;
 
706
  /* Make ARG the last on the list.  */
 
707
  arg_list->last_argument = arg;
 
708
  arg->next = NULL;
 
709
}
 
710
 
 
711
/* Returns the template arugment at position INDEX in template
 
712
   argument list ARG_LIST.  */
 
713
 
 
714
static string_list_t
 
715
template_arg_list_get_arg (arg_list, index)
 
716
     template_arg_list_t arg_list;
 
717
     int index;
 
718
{
 
719
  string_list_t arg = arg_list->first_argument;
 
720
  /* Scan down the list of arguments to find the one at position
 
721
     INDEX.  */
 
722
  while (index--)
 
723
    {
 
724
      arg = arg->next;
 
725
      if (arg == NULL)
 
726
        /* Ran out of arguments before INDEX hit zero.  That's an
 
727
           error.  */
 
728
        return NULL;
 
729
    }
 
730
  /* Return the argument at position INDEX.  */
 
731
  return arg;
 
732
}
 
733
 
 
734
/* Pushes ARG_LIST onto the top of the template argument list stack.  */
 
735
 
 
736
static void
 
737
push_template_arg_list (dm, arg_list)
 
738
     demangling_t dm;
 
739
     template_arg_list_t arg_list;
 
740
{
 
741
  arg_list->next = dm->template_arg_lists;
 
742
  dm->template_arg_lists = arg_list;
 
743
#ifdef CP_DEMANGLE_DEBUG
 
744
  fprintf (stderr, " ** pushing template arg list\n");
 
745
  template_arg_list_print (arg_list, stderr);
 
746
#endif 
 
747
}
 
748
 
 
749
/* Pops and deletes elements on the template argument list stack until
 
750
   arg_list is the topmost element.  If arg_list is NULL, all elements
 
751
   are popped and deleted.  */
 
752
 
 
753
static void
 
754
pop_to_template_arg_list (dm, arg_list)
 
755
     demangling_t dm;
 
756
     template_arg_list_t arg_list;
 
757
{
 
758
  while (dm->template_arg_lists != arg_list)
 
759
    {
 
760
      template_arg_list_t top = dm->template_arg_lists;
 
761
      /* Disconnect the topmost element from the list.  */
 
762
      dm->template_arg_lists = top->next;
 
763
      /* Delete the popped element.  */
 
764
      template_arg_list_delete (top);
 
765
#ifdef CP_DEMANGLE_DEBUG
 
766
      fprintf (stderr, " ** removing template arg list\n");
 
767
#endif
 
768
    }
 
769
}
 
770
 
 
771
#ifdef CP_DEMANGLE_DEBUG
 
772
 
 
773
/* Prints the contents of ARG_LIST to FP.  */
 
774
 
 
775
static void
 
776
template_arg_list_print (arg_list, fp)
 
777
  template_arg_list_t arg_list;
 
778
  FILE *fp;
 
779
{
 
780
  string_list_t arg;
 
781
  int index = -1;
 
782
 
 
783
  fprintf (fp, "TEMPLATE ARGUMENT LIST:\n");
 
784
  for (arg = arg_list->first_argument; arg != NULL; arg = arg->next)
 
785
    {
 
786
      if (index == -1)
 
787
        fprintf (fp, " T_  : ");
 
788
      else
 
789
        fprintf (fp, " T%d_ : ", index);
 
790
      ++index;
 
791
      fprintf (fp, "%s\n", dyn_string_buf ((dyn_string_t) arg));
 
792
    }
 
793
}
 
794
 
 
795
#endif /* CP_DEMANGLE_DEBUG */
 
796
 
 
797
/* Returns the topmost element on the stack of template argument
 
798
   lists.  If there is no list of template arguments, returns NULL.  */
 
799
 
 
800
static template_arg_list_t
 
801
current_template_arg_list (dm)
 
802
     demangling_t dm;
 
803
{
 
804
  return dm->template_arg_lists;
 
805
}
 
806
 
 
807
/* Allocates a demangling_t object for demangling mangled NAME.  A new
 
808
   result must be pushed before the returned object can be used.
 
809
   Returns NULL if allocation fails.  */
 
810
 
 
811
static demangling_t
 
812
demangling_new (name, style)
 
813
     const char *name;
 
814
     int style;
 
815
{
 
816
  demangling_t dm;
 
817
  dm = (demangling_t) malloc (sizeof (struct demangling_def));
 
818
  if (dm == NULL)
 
819
    return NULL;
 
820
 
 
821
  dm->name = name;
 
822
  dm->next = name;
 
823
  dm->result = NULL;
 
824
  dm->num_substitutions = 0;
 
825
  dm->substitutions_allocated = 10;
 
826
  dm->template_arg_lists = NULL;
 
827
  dm->last_source_name = dyn_string_new (0);
 
828
  if (dm->last_source_name == NULL)
 
829
    return NULL;
 
830
  dm->substitutions = (struct substitution_def *)
 
831
    malloc (dm->substitutions_allocated * sizeof (struct substitution_def));
 
832
  if (dm->substitutions == NULL)
 
833
    {
 
834
      dyn_string_delete (dm->last_source_name);
 
835
      return NULL;
 
836
    }
 
837
  dm->style = style;
 
838
  dm->is_constructor = 0;
 
839
  dm->is_destructor = 0;
 
840
 
 
841
  return dm;
 
842
}
 
843
 
 
844
/* Deallocates a demangling_t object and all memory associated with
 
845
   it.  */
 
846
 
 
847
static void
 
848
demangling_delete (dm)
 
849
     demangling_t dm;
 
850
{
 
851
  int i;
 
852
  template_arg_list_t arg_list = dm->template_arg_lists;
 
853
 
 
854
  /* Delete the stack of template argument lists.  */
 
855
  while (arg_list != NULL)
 
856
    {
 
857
      template_arg_list_t next = arg_list->next;
 
858
      template_arg_list_delete (arg_list);
 
859
      arg_list = next;
 
860
    }
 
861
  /* Delete the list of substitutions.  */
 
862
  for (i = dm->num_substitutions; --i >= 0; )
 
863
    dyn_string_delete (dm->substitutions[i].text);
 
864
  free (dm->substitutions);
 
865
  /* Delete the demangled result.  */
 
866
  string_list_delete (dm->result);
 
867
  /* Delete the stored identifier name.  */
 
868
  dyn_string_delete (dm->last_source_name);
 
869
  /* Delete the context object itself.  */
 
870
  free (dm);
 
871
}
 
872
 
 
873
/* These functions demangle an alternative of the corresponding
 
874
   production in the mangling spec.  The first argument of each is a
 
875
   demangling context structure for the current demangling
 
876
   operation.  Most emit demangled text directly to the topmost result
 
877
   string on the result string stack in the demangling context
 
878
   structure.  */
 
879
 
 
880
static status_t demangle_char
 
881
  PARAMS ((demangling_t, int));
 
882
static status_t demangle_mangled_name 
 
883
  PARAMS ((demangling_t));
 
884
static status_t demangle_encoding
 
885
  PARAMS ((demangling_t));
 
886
static status_t demangle_name
 
887
  PARAMS ((demangling_t, int *));
 
888
static status_t demangle_nested_name
 
889
  PARAMS ((demangling_t, int *));
 
890
static status_t demangle_prefix
 
891
  PARAMS ((demangling_t, int *));
 
892
static status_t demangle_unqualified_name
 
893
  PARAMS ((demangling_t, int *));
 
894
static status_t demangle_source_name
 
895
  PARAMS ((demangling_t));
 
896
static status_t demangle_number
 
897
  PARAMS ((demangling_t, int *, int, int));
 
898
static status_t demangle_number_literally
 
899
  PARAMS ((demangling_t, dyn_string_t, int, int));
 
900
static status_t demangle_identifier
 
901
  PARAMS ((demangling_t, int, dyn_string_t));
 
902
static status_t demangle_operator_name
 
903
  PARAMS ((demangling_t, int, int *, int *));
 
904
static status_t demangle_nv_offset
 
905
  PARAMS ((demangling_t));
 
906
static status_t demangle_v_offset
 
907
  PARAMS ((demangling_t));
 
908
static status_t demangle_call_offset
 
909
  PARAMS ((demangling_t));
 
910
static status_t demangle_special_name
 
911
  PARAMS ((demangling_t));
 
912
static status_t demangle_ctor_dtor_name
 
913
  PARAMS ((demangling_t));
 
914
static status_t demangle_type_ptr
 
915
  PARAMS ((demangling_t, int *, int));
 
916
static status_t demangle_type
 
917
  PARAMS ((demangling_t));
 
918
static status_t demangle_CV_qualifiers
 
919
  PARAMS ((demangling_t, dyn_string_t));
 
920
static status_t demangle_builtin_type
 
921
  PARAMS ((demangling_t));
 
922
static status_t demangle_function_type
 
923
  PARAMS ((demangling_t, int *));
 
924
static status_t demangle_bare_function_type
 
925
  PARAMS ((demangling_t, int *));
 
926
static status_t demangle_class_enum_type
 
927
  PARAMS ((demangling_t, int *));
 
928
static status_t demangle_array_type
 
929
  PARAMS ((demangling_t, int *));
 
930
static status_t demangle_template_param
 
931
  PARAMS ((demangling_t));
 
932
static status_t demangle_template_args
 
933
  PARAMS ((demangling_t));
 
934
static status_t demangle_literal
 
935
  PARAMS ((demangling_t));
 
936
static status_t demangle_template_arg
 
937
  PARAMS ((demangling_t));
 
938
static status_t demangle_expression
 
939
  PARAMS ((demangling_t));
 
940
static status_t demangle_scope_expression
 
941
  PARAMS ((demangling_t));
 
942
static status_t demangle_expr_primary
 
943
  PARAMS ((demangling_t));
 
944
static status_t demangle_substitution
 
945
  PARAMS ((demangling_t, int *));
 
946
static status_t demangle_local_name
 
947
  PARAMS ((demangling_t));
 
948
static status_t demangle_discriminator 
 
949
  PARAMS ((demangling_t, int));
 
950
static status_t cp_demangle
 
951
  PARAMS ((const char *, dyn_string_t, int));
 
952
static status_t cp_demangle_type
 
953
  PARAMS ((const char*, dyn_string_t));
 
954
 
 
955
/* When passed to demangle_bare_function_type, indicates that the
 
956
   function's return type is not encoded before its parameter types.  */
 
957
#define BFT_NO_RETURN_TYPE    NULL
 
958
 
 
959
/* Check that the next character is C.  If so, consume it.  If not,
 
960
   return an error.  */
 
961
 
 
962
static status_t
 
963
demangle_char (dm, c)
 
964
     demangling_t dm;
 
965
     int c;
 
966
{
 
967
  static char *error_message = NULL;
 
968
 
 
969
  if (peek_char (dm) == c)
 
970
    {
 
971
      advance_char (dm);
 
972
      return STATUS_OK;
 
973
    }
 
974
  else
 
975
    {
 
976
      if (error_message == NULL)
 
977
        error_message = strdup ("Expected ?");
 
978
      error_message[9] = c;
 
979
      return error_message;
 
980
    }
 
981
}
 
982
 
 
983
/* Demangles and emits a <mangled-name>.  
 
984
 
 
985
    <mangled-name>      ::= _Z <encoding>  */
 
986
 
 
987
static status_t
 
988
demangle_mangled_name (dm)
 
989
     demangling_t dm;
 
990
{
 
991
  DEMANGLE_TRACE ("mangled-name", dm);
 
992
  RETURN_IF_ERROR (demangle_char (dm, '_'));
 
993
  RETURN_IF_ERROR (demangle_char (dm, 'Z'));
 
994
  RETURN_IF_ERROR (demangle_encoding (dm));
 
995
  return STATUS_OK;
 
996
}
 
997
 
 
998
/* Demangles and emits an <encoding>.  
 
999
 
 
1000
    <encoding>          ::= <function name> <bare-function-type>
 
1001
                        ::= <data name>
 
1002
                        ::= <special-name>  */
 
1003
 
 
1004
static status_t
 
1005
demangle_encoding (dm)
 
1006
     demangling_t dm;
 
1007
{
 
1008
  int encode_return_type;
 
1009
  int start_position;
 
1010
  template_arg_list_t old_arg_list = current_template_arg_list (dm);
 
1011
  char peek = peek_char (dm);
 
1012
 
 
1013
  DEMANGLE_TRACE ("encoding", dm);
 
1014
  
 
1015
  /* Remember where the name starts.  If it turns out to be a template
 
1016
     function, we'll have to insert the return type here.  */
 
1017
  start_position = result_caret_pos (dm);
 
1018
 
 
1019
  if (peek == 'G' || peek == 'T')
 
1020
    RETURN_IF_ERROR (demangle_special_name (dm));
 
1021
  else
 
1022
    {
 
1023
      /* Now demangle the name.  */
 
1024
      RETURN_IF_ERROR (demangle_name (dm, &encode_return_type));
 
1025
 
 
1026
      /* If there's anything left, the name was a function name, with
 
1027
         maybe its return type, and its parameter types, following.  */
 
1028
      if (!end_of_name_p (dm) 
 
1029
          && peek_char (dm) != 'E')
 
1030
        {
 
1031
          if (encode_return_type)
 
1032
            /* Template functions have their return type encoded.  The
 
1033
               return type should be inserted at start_position.  */
 
1034
            RETURN_IF_ERROR 
 
1035
              (demangle_bare_function_type (dm, &start_position));
 
1036
          else
 
1037
            /* Non-template functions don't have their return type
 
1038
               encoded.  */
 
1039
            RETURN_IF_ERROR 
 
1040
              (demangle_bare_function_type (dm, BFT_NO_RETURN_TYPE)); 
 
1041
        }
 
1042
    }
 
1043
 
 
1044
  /* Pop off template argument lists that were built during the
 
1045
     mangling of this name, to restore the old template context.  */
 
1046
  pop_to_template_arg_list (dm, old_arg_list);
 
1047
 
 
1048
  return STATUS_OK;
 
1049
}
 
1050
 
 
1051
/* Demangles and emits a <name>.
 
1052
 
 
1053
    <name>              ::= <unscoped-name>
 
1054
                        ::= <unscoped-template-name> <template-args>
 
1055
                        ::= <nested-name>
 
1056
                        ::= <local-name>
 
1057
 
 
1058
    <unscoped-name>     ::= <unqualified-name>
 
1059
                        ::= St <unqualified-name>   # ::std::
 
1060
 
 
1061
    <unscoped-template-name>    
 
1062
                        ::= <unscoped-name>
 
1063
                        ::= <substitution>  */
 
1064
 
 
1065
static status_t
 
1066
demangle_name (dm, encode_return_type)
 
1067
     demangling_t dm;
 
1068
     int *encode_return_type;
 
1069
{
 
1070
  int start = substitution_start (dm);
 
1071
  char peek = peek_char (dm);
 
1072
  int is_std_substitution = 0;
 
1073
 
 
1074
  /* Generally, the return type is encoded if the function is a
 
1075
     template-id, and suppressed otherwise.  There are a few cases,
 
1076
     though, in which the return type is not encoded even for a
 
1077
     templated function.  In these cases, this flag is set.  */
 
1078
  int suppress_return_type = 0;
 
1079
 
 
1080
  DEMANGLE_TRACE ("name", dm);
 
1081
 
 
1082
  switch (peek)
 
1083
    {
 
1084
    case 'N':
 
1085
      /* This is a <nested-name>.  */
 
1086
      RETURN_IF_ERROR (demangle_nested_name (dm, encode_return_type));
 
1087
      break;
 
1088
 
 
1089
    case 'Z':
 
1090
      RETURN_IF_ERROR (demangle_local_name (dm));
 
1091
      *encode_return_type = 0;
 
1092
      break;
 
1093
 
 
1094
    case 'S':
 
1095
      /* The `St' substitution allows a name nested in std:: to appear
 
1096
         without being enclosed in a nested name.  */
 
1097
      if (peek_char_next (dm) == 't') 
 
1098
        {
 
1099
          (void) next_char (dm);
 
1100
          (void) next_char (dm);
 
1101
          RETURN_IF_ERROR (result_add (dm, "std::"));
 
1102
          RETURN_IF_ERROR 
 
1103
            (demangle_unqualified_name (dm, &suppress_return_type));
 
1104
          is_std_substitution = 1;
 
1105
        }
 
1106
      else
 
1107
        RETURN_IF_ERROR (demangle_substitution (dm, encode_return_type));
 
1108
      /* Check if a template argument list immediately follows.
 
1109
         If so, then we just demangled an <unqualified-template-name>.  */
 
1110
      if (peek_char (dm) == 'I') 
 
1111
        {
 
1112
          /* A template name of the form std::<unqualified-name> is a
 
1113
             substitution candidate.  */
 
1114
          if (is_std_substitution)
 
1115
            RETURN_IF_ERROR (substitution_add (dm, start, 0));
 
1116
          /* Demangle the <template-args> here.  */
 
1117
          RETURN_IF_ERROR (demangle_template_args (dm));
 
1118
          *encode_return_type = !suppress_return_type;
 
1119
        }
 
1120
      else
 
1121
        *encode_return_type = 0;
 
1122
 
 
1123
      break;
 
1124
 
 
1125
    default:
 
1126
      /* This is an <unscoped-name> or <unscoped-template-name>.  */
 
1127
      RETURN_IF_ERROR (demangle_unqualified_name (dm, &suppress_return_type));
 
1128
 
 
1129
      /* If the <unqualified-name> is followed by template args, this
 
1130
         is an <unscoped-template-name>.  */
 
1131
      if (peek_char (dm) == 'I')
 
1132
        {
 
1133
          /* Add a substitution for the unqualified template name.  */
 
1134
          RETURN_IF_ERROR (substitution_add (dm, start, 0));
 
1135
 
 
1136
          RETURN_IF_ERROR (demangle_template_args (dm));
 
1137
          *encode_return_type = !suppress_return_type;
 
1138
        }
 
1139
      else
 
1140
        *encode_return_type = 0;
 
1141
 
 
1142
      break;
 
1143
    }
 
1144
 
 
1145
  return STATUS_OK;
 
1146
}
 
1147
 
 
1148
/* Demangles and emits a <nested-name>. 
 
1149
 
 
1150
    <nested-name>     ::= N [<CV-qualifiers>] <prefix> <unqulified-name> E  */
 
1151
 
 
1152
static status_t
 
1153
demangle_nested_name (dm, encode_return_type)
 
1154
     demangling_t dm;
 
1155
     int *encode_return_type;
 
1156
{
 
1157
  char peek;
 
1158
 
 
1159
  DEMANGLE_TRACE ("nested-name", dm);
 
1160
 
 
1161
  RETURN_IF_ERROR (demangle_char (dm, 'N'));
 
1162
 
 
1163
  peek = peek_char (dm);
 
1164
  if (peek == 'r' || peek == 'V' || peek == 'K')
 
1165
    {
 
1166
      dyn_string_t cv_qualifiers;
 
1167
      status_t status;
 
1168
 
 
1169
      /* Snarf up CV qualifiers.  */
 
1170
      cv_qualifiers = dyn_string_new (24);
 
1171
      if (cv_qualifiers == NULL)
 
1172
        return STATUS_ALLOCATION_FAILED;
 
1173
      demangle_CV_qualifiers (dm, cv_qualifiers);
 
1174
 
 
1175
      /* Emit them, preceded by a space.  */
 
1176
      status = result_add_char (dm, ' ');
 
1177
      if (STATUS_NO_ERROR (status)) 
 
1178
        status = result_add_string (dm, cv_qualifiers);
 
1179
      /* The CV qualifiers that occur in a <nested-name> will be
 
1180
         qualifiers for member functions.  These are placed at the end
 
1181
         of the function.  Therefore, shift the caret to the left by
 
1182
         the length of the qualifiers, so other text is inserted
 
1183
         before them and they stay at the end.  */
 
1184
      result_shift_caret (dm, -dyn_string_length (cv_qualifiers) - 1);
 
1185
      /* Clean up.  */
 
1186
      dyn_string_delete (cv_qualifiers);
 
1187
      RETURN_IF_ERROR (status);
 
1188
    }
 
1189
 
 
1190
  RETURN_IF_ERROR (demangle_prefix (dm, encode_return_type));
 
1191
  /* No need to demangle the final <unqualified-name>; demangle_prefix
 
1192
     will handle it.  */
 
1193
  RETURN_IF_ERROR (demangle_char (dm, 'E'));
 
1194
 
 
1195
  return STATUS_OK;
 
1196
}
 
1197
 
 
1198
/* Demangles and emits a <prefix>.
 
1199
 
 
1200
    <prefix>            ::= <prefix> <unqualified-name>
 
1201
                        ::= <template-prefix> <template-args>
 
1202
                        ::= # empty
 
1203
                        ::= <substitution>
 
1204
 
 
1205
    <template-prefix>   ::= <prefix>
 
1206
                        ::= <substitution>  */
 
1207
 
 
1208
static status_t
 
1209
demangle_prefix (dm, encode_return_type)
 
1210
     demangling_t dm;
 
1211
     int *encode_return_type;
 
1212
{
 
1213
  int start = substitution_start (dm);
 
1214
  int nested = 0;
 
1215
 
 
1216
  /* ENCODE_RETURN_TYPE is updated as we decend the nesting chain.
 
1217
     After <template-args>, it is set to non-zero; after everything
 
1218
     else it is set to zero.  */
 
1219
 
 
1220
  /* Generally, the return type is encoded if the function is a
 
1221
     template-id, and suppressed otherwise.  There are a few cases,
 
1222
     though, in which the return type is not encoded even for a
 
1223
     templated function.  In these cases, this flag is set.  */
 
1224
  int suppress_return_type = 0;
 
1225
 
 
1226
  DEMANGLE_TRACE ("prefix", dm);
 
1227
 
 
1228
  while (1)
 
1229
    {
 
1230
      char peek;
 
1231
 
 
1232
      if (end_of_name_p (dm))
 
1233
        return "Unexpected end of name in <compound-name>.";
 
1234
 
 
1235
      peek = peek_char (dm);
 
1236
      
 
1237
      /* We'll initialize suppress_return_type to false, and set it to true
 
1238
         if we end up demangling a constructor name.  However, make
 
1239
         sure we're not actually about to demangle template arguments
 
1240
         -- if so, this is the <template-args> following a
 
1241
         <template-prefix>, so we'll want the previous flag value
 
1242
         around.  */
 
1243
      if (peek != 'I')
 
1244
        suppress_return_type = 0;
 
1245
 
 
1246
      if (IS_DIGIT ((unsigned char) peek)
 
1247
          || (peek >= 'a' && peek <= 'z')
 
1248
          || peek == 'C' || peek == 'D'
 
1249
          || peek == 'S')
 
1250
        {
 
1251
          /* We have another level of scope qualification.  */
 
1252
          if (nested)
 
1253
            RETURN_IF_ERROR (result_add (dm, NAMESPACE_SEPARATOR));
 
1254
          else
 
1255
            nested = 1;
 
1256
 
 
1257
          if (peek == 'S')
 
1258
            /* The substitution determines whether this is a
 
1259
               template-id.  */
 
1260
            RETURN_IF_ERROR (demangle_substitution (dm, encode_return_type));
 
1261
          else
 
1262
            {
 
1263
              /* It's just a name.  */
 
1264
              RETURN_IF_ERROR 
 
1265
                (demangle_unqualified_name (dm, &suppress_return_type));
 
1266
              *encode_return_type = 0;
 
1267
            }
 
1268
        }
 
1269
      else if (peek == 'Z')
 
1270
        RETURN_IF_ERROR (demangle_local_name (dm));
 
1271
      else if (peek == 'I')
 
1272
        {
 
1273
          RETURN_IF_ERROR (demangle_template_args (dm));
 
1274
 
 
1275
          /* Now we want to indicate to the caller that we've
 
1276
             demangled template arguments, thus the prefix was a
 
1277
             <template-prefix>.  That's so that the caller knows to
 
1278
             demangle the function's return type, if this turns out to
 
1279
             be a function name.  But, if it's a member template
 
1280
             constructor or a templated conversion operator, report it
 
1281
             as untemplated.  Those never get encoded return types.  */
 
1282
          *encode_return_type = !suppress_return_type;
 
1283
        }
 
1284
      else if (peek == 'E')
 
1285
        /* All done.  */
 
1286
        return STATUS_OK;
 
1287
      else
 
1288
        return "Unexpected character in <compound-name>.";
 
1289
 
 
1290
      if (peek != 'S'
 
1291
          && peek_char (dm) != 'E')
 
1292
        /* Add a new substitution for the prefix thus far.  */
 
1293
        RETURN_IF_ERROR (substitution_add (dm, start, *encode_return_type));
 
1294
    }
 
1295
}
 
1296
 
 
1297
/* Demangles and emits an <unqualified-name>.  If this
 
1298
   <unqualified-name> is for a special function type that should never
 
1299
   have its return type encoded (particularly, a constructor or
 
1300
   conversion operator), *SUPPRESS_RETURN_TYPE is set to 1; otherwise,
 
1301
   it is set to zero.
 
1302
 
 
1303
    <unqualified-name>  ::= <operator-name>
 
1304
                        ::= <special-name>  
 
1305
                        ::= <source-name>  */
 
1306
 
 
1307
static status_t
 
1308
demangle_unqualified_name (dm, suppress_return_type)
 
1309
     demangling_t dm;
 
1310
     int *suppress_return_type;
 
1311
{
 
1312
  char peek = peek_char (dm);
 
1313
 
 
1314
  DEMANGLE_TRACE ("unqualified-name", dm);
 
1315
 
 
1316
  /* By default, don't force suppression of the return type (though
 
1317
     non-template functions still don't get a return type encoded).  */ 
 
1318
  *suppress_return_type = 0;
 
1319
 
 
1320
  if (IS_DIGIT ((unsigned char) peek))
 
1321
    RETURN_IF_ERROR (demangle_source_name (dm));
 
1322
  else if (peek >= 'a' && peek <= 'z')
 
1323
    {
 
1324
      int num_args;
 
1325
 
 
1326
      /* Conversion operators never have a return type encoded.  */
 
1327
      if (peek == 'c' && peek_char_next (dm) == 'v')
 
1328
        *suppress_return_type = 1;
 
1329
 
 
1330
      RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args, NULL));
 
1331
    }
 
1332
  else if (peek == 'C' || peek == 'D')
 
1333
    {
 
1334
      /* Constructors never have a return type encoded.  */
 
1335
      if (peek == 'C')
 
1336
        *suppress_return_type = 1;
 
1337
 
 
1338
      RETURN_IF_ERROR (demangle_ctor_dtor_name (dm));
 
1339
    }
 
1340
  else
 
1341
    return "Unexpected character in <unqualified-name>.";
 
1342
 
 
1343
  return STATUS_OK;
 
1344
}
 
1345
 
 
1346
/* Demangles and emits <source-name>.  
 
1347
 
 
1348
    <source-name> ::= <length number> <identifier>  */
 
1349
 
 
1350
static status_t
 
1351
demangle_source_name (dm)
 
1352
     demangling_t dm;
 
1353
{
 
1354
  int length;
 
1355
 
 
1356
  DEMANGLE_TRACE ("source-name", dm);
 
1357
 
 
1358
  /* Decode the length of the identifier.  */
 
1359
  RETURN_IF_ERROR (demangle_number (dm, &length, 10, 0));
 
1360
  if (length == 0)
 
1361
    return "Zero length in <source-name>.";
 
1362
 
 
1363
  /* Now the identifier itself.  It's placed into last_source_name,
 
1364
     where it can be used to build a constructor or destructor name.  */
 
1365
  RETURN_IF_ERROR (demangle_identifier (dm, length, 
 
1366
                                        dm->last_source_name));
 
1367
 
 
1368
  /* Emit it.  */
 
1369
  RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
 
1370
 
 
1371
  return STATUS_OK;
 
1372
}
 
1373
 
 
1374
/* Demangles a number, either a <number> or a <positive-number> at the
 
1375
   current position, consuming all consecutive digit characters.  Sets
 
1376
   *VALUE to the resulting numberand returns STATUS_OK.  The number is
 
1377
   interpreted as BASE, which must be either 10 or 36.  If IS_SIGNED
 
1378
   is non-zero, negative numbers -- prefixed with `n' -- are accepted.
 
1379
 
 
1380
    <number> ::= [n] <positive-number>
 
1381
 
 
1382
    <positive-number> ::= <decimal integer>  */
 
1383
 
 
1384
static status_t
 
1385
demangle_number (dm, value, base, is_signed)
 
1386
     demangling_t dm;
 
1387
     int *value;
 
1388
     int base;
 
1389
     int is_signed;
 
1390
{
 
1391
  dyn_string_t number = dyn_string_new (10);
 
1392
 
 
1393
  DEMANGLE_TRACE ("number", dm);
 
1394
 
 
1395
  if (number == NULL)
 
1396
    return STATUS_ALLOCATION_FAILED;
 
1397
 
 
1398
  demangle_number_literally (dm, number, base, is_signed);
 
1399
  *value = strtol (dyn_string_buf (number), NULL, base);
 
1400
  dyn_string_delete (number);
 
1401
 
 
1402
  return STATUS_OK;
 
1403
}
 
1404
 
 
1405
/* Demangles a number at the current position.  The digits (and minus
 
1406
   sign, if present) that make up the number are appended to STR.
 
1407
   Only base-BASE digits are accepted; BASE must be either 10 or 36.
 
1408
   If IS_SIGNED, negative numbers -- prefixed with `n' -- are
 
1409
   accepted.  Does not consume a trailing underscore or other
 
1410
   terminating character.  */
 
1411
 
 
1412
static status_t
 
1413
demangle_number_literally (dm, str, base, is_signed)
 
1414
     demangling_t dm;
 
1415
     dyn_string_t str;
 
1416
     int base;
 
1417
     int is_signed;
 
1418
{
 
1419
  DEMANGLE_TRACE ("number*", dm);
 
1420
 
 
1421
  if (base != 10 && base != 36)
 
1422
    return STATUS_INTERNAL_ERROR;
 
1423
 
 
1424
  /* An `n' denotes a negative number.  */
 
1425
  if (is_signed && peek_char (dm) == 'n')
 
1426
    {
 
1427
      /* Skip past the n.  */
 
1428
      advance_char (dm);
 
1429
      /* The normal way to write a negative number is with a minus
 
1430
         sign.  */
 
1431
      if (!dyn_string_append_char (str, '-'))
 
1432
        return STATUS_ALLOCATION_FAILED;
 
1433
    }
 
1434
 
 
1435
  /* Loop until we hit a non-digit.  */
 
1436
  while (1)
 
1437
    {
 
1438
      char peek = peek_char (dm);
 
1439
      if (IS_DIGIT ((unsigned char) peek)
 
1440
          || (base == 36 && peek >= 'A' && peek <= 'Z'))
 
1441
        {
 
1442
          /* Accumulate digits.  */
 
1443
          if (!dyn_string_append_char (str, next_char (dm)))
 
1444
            return STATUS_ALLOCATION_FAILED;
 
1445
        }
 
1446
      else
 
1447
        /* Not a digit?  All done.  */
 
1448
        break;
 
1449
    }
 
1450
 
 
1451
  return STATUS_OK;
 
1452
}
 
1453
 
 
1454
/* Demangles an identifier at the current position of LENGTH
 
1455
   characters and places it in IDENTIFIER.  */
 
1456
 
 
1457
static status_t
 
1458
demangle_identifier (dm, length, identifier)
 
1459
     demangling_t dm;
 
1460
     int length;
 
1461
     dyn_string_t identifier;
 
1462
{
 
1463
  DEMANGLE_TRACE ("identifier", dm);
 
1464
 
 
1465
  dyn_string_clear (identifier);
 
1466
  if (!dyn_string_resize (identifier, length))
 
1467
    return STATUS_ALLOCATION_FAILED;
 
1468
 
 
1469
  while (length-- > 0)
 
1470
    {
 
1471
      int ch;
 
1472
      if (end_of_name_p (dm))
 
1473
        return "Unexpected end of name in <identifier>.";
 
1474
      ch = next_char (dm);
 
1475
 
 
1476
      /* Handle extended Unicode characters.  We encode them as __U{hex}_,
 
1477
         where {hex} omits leading 0's.  For instance, '$' is encoded as
 
1478
         "__U24_".  */
 
1479
      if (ch == '_'
 
1480
          && peek_char (dm) == '_'
 
1481
          && peek_char_next (dm) == 'U')
 
1482
        {
 
1483
          char buf[10];
 
1484
          int pos = 0;
 
1485
          advance_char (dm); advance_char (dm); length -= 2;
 
1486
          while (length-- > 0)
 
1487
            {
 
1488
              ch = next_char (dm);
 
1489
              if (!isxdigit (ch))
 
1490
                break;
 
1491
              buf[pos++] = ch;
 
1492
            }
 
1493
          if (ch != '_' || length < 0)
 
1494
            return STATUS_ERROR;
 
1495
          if (pos == 0)
 
1496
            {
 
1497
              /* __U_ just means __U.  */
 
1498
              if (!dyn_string_append_cstr (identifier, "__U"))
 
1499
                return STATUS_ALLOCATION_FAILED;
 
1500
              continue;
 
1501
            }
 
1502
          else
 
1503
            {
 
1504
              buf[pos] = '\0';
 
1505
              ch = strtol (buf, 0, 16);
 
1506
            }
 
1507
        }
 
1508
 
 
1509
      if (!dyn_string_append_char (identifier, ch))
 
1510
        return STATUS_ALLOCATION_FAILED;
 
1511
    }
 
1512
 
 
1513
  /* GCC encodes anonymous namespaces using a `_GLOBAL_[_.$]N.'
 
1514
     followed by the source file name and some random characters.
 
1515
     Unless we're in strict mode, decipher these names appropriately.  */
 
1516
  if (!flag_strict)
 
1517
    {
 
1518
      char *name = dyn_string_buf (identifier);
 
1519
      int prefix_length = strlen (ANONYMOUS_NAMESPACE_PREFIX);
 
1520
 
 
1521
      /* Compare the first, fixed part.  */
 
1522
      if (strncmp (name, ANONYMOUS_NAMESPACE_PREFIX, prefix_length) == 0)
 
1523
        {
 
1524
          name += prefix_length;
 
1525
          /* The next character might be a period, an underscore, or
 
1526
             dollar sign, depending on the target architecture's
 
1527
             assembler's capabilities.  After that comes an `N'.  */
 
1528
          if ((*name == '.' || *name == '_' || *name == '$')
 
1529
              && *(name + 1) == 'N')
 
1530
            /* This looks like the anonymous namespace identifier.
 
1531
               Replace it with something comprehensible.  */
 
1532
            dyn_string_copy_cstr (identifier, "(anonymous namespace)");
 
1533
        }
 
1534
    }
 
1535
 
 
1536
  return STATUS_OK;
 
1537
}
 
1538
 
 
1539
/* Demangles and emits an <operator-name>.  If SHORT_NAME is non-zero,
 
1540
   the short form is emitted; otherwise the full source form
 
1541
   (`operator +' etc.) is emitted.  *NUM_ARGS is set to the number of
 
1542
   operands that the operator takes.  If TYPE_ARG is non-NULL,
 
1543
   *TYPE_ARG is set to 1 if the first argument is a type and 0
 
1544
   otherwise.
 
1545
 
 
1546
    <operator-name>
 
1547
                  ::= nw        # new           
 
1548
                  ::= na        # new[]
 
1549
                  ::= dl        # delete        
 
1550
                  ::= da        # delete[]      
 
1551
                  ::= ps        # + (unary)
 
1552
                  ::= ng        # - (unary)     
 
1553
                  ::= ad        # & (unary)     
 
1554
                  ::= de        # * (unary)     
 
1555
                  ::= co        # ~             
 
1556
                  ::= pl        # +             
 
1557
                  ::= mi        # -             
 
1558
                  ::= ml        # *             
 
1559
                  ::= dv        # /             
 
1560
                  ::= rm        # %             
 
1561
                  ::= an        # &             
 
1562
                  ::= or        # |             
 
1563
                  ::= eo        # ^             
 
1564
                  ::= aS        # =             
 
1565
                  ::= pL        # +=            
 
1566
                  ::= mI        # -=            
 
1567
                  ::= mL        # *=            
 
1568
                  ::= dV        # /=            
 
1569
                  ::= rM        # %=            
 
1570
                  ::= aN        # &=            
 
1571
                  ::= oR        # |=            
 
1572
                  ::= eO        # ^=            
 
1573
                  ::= ls        # <<            
 
1574
                  ::= rs        # >>            
 
1575
                  ::= lS        # <<=           
 
1576
                  ::= rS        # >>=           
 
1577
                  ::= eq        # ==            
 
1578
                  ::= ne        # !=            
 
1579
                  ::= lt        # <             
 
1580
                  ::= gt        # >             
 
1581
                  ::= le        # <=            
 
1582
                  ::= ge        # >=            
 
1583
                  ::= nt        # !             
 
1584
                  ::= aa        # &&            
 
1585
                  ::= oo        # ||            
 
1586
                  ::= pp        # ++            
 
1587
                  ::= mm        # --            
 
1588
                  ::= cm        # ,             
 
1589
                  ::= pm        # ->*           
 
1590
                  ::= pt        # ->            
 
1591
                  ::= cl        # ()            
 
1592
                  ::= ix        # []            
 
1593
                  ::= qu        # ?
 
1594
                  ::= st        # sizeof (a type)
 
1595
                  ::= sz        # sizeof (an expression)
 
1596
                  ::= cv <type> # cast        
 
1597
                  ::= v [0-9] <source-name>  # vendor extended operator  */
 
1598
 
 
1599
static status_t
 
1600
demangle_operator_name (dm, short_name, num_args, type_arg)
 
1601
     demangling_t dm;
 
1602
     int short_name;
 
1603
     int *num_args;
 
1604
     int *type_arg;
 
1605
{
 
1606
  struct operator_code
 
1607
  {
 
1608
    /* The mangled code for this operator.  */
 
1609
    const char *const code;
 
1610
    /* The source name of this operator.  */
 
1611
    const char *const name;
 
1612
    /* The number of arguments this operator takes.  */
 
1613
    const int num_args;
 
1614
  };
 
1615
 
 
1616
  static const struct operator_code operators[] = 
 
1617
  {
 
1618
    { "aN", "&="       , 2 },
 
1619
    { "aS", "="        , 2 },
 
1620
    { "aa", "&&"       , 2 },
 
1621
    { "ad", "&"        , 1 },
 
1622
    { "an", "&"        , 2 },
 
1623
    { "cl", "()"       , 0 },
 
1624
    { "cm", ","        , 2 },
 
1625
    { "co", "~"        , 1 },
 
1626
    { "dV", "/="       , 2 },
 
1627
    { "da", " delete[]", 1 },
 
1628
    { "de", "*"        , 1 },
 
1629
    { "dl", " delete"  , 1 },
 
1630
    { "dv", "/"        , 2 },
 
1631
    { "eO", "^="       , 2 },
 
1632
    { "eo", "^"        , 2 },
 
1633
    { "eq", "=="       , 2 },
 
1634
    { "ge", ">="       , 2 },
 
1635
    { "gt", ">"        , 2 },
 
1636
    { "ix", "[]"       , 2 },
 
1637
    { "lS", "<<="      , 2 },
 
1638
    { "le", "<="       , 2 },
 
1639
    { "ls", "<<"       , 2 },
 
1640
    { "lt", "<"        , 2 },
 
1641
    { "mI", "-="       , 2 },
 
1642
    { "mL", "*="       , 2 },
 
1643
    { "mi", "-"        , 2 },
 
1644
    { "ml", "*"        , 2 },
 
1645
    { "mm", "--"       , 1 },
 
1646
    { "na", " new[]"   , 1 },
 
1647
    { "ne", "!="       , 2 },
 
1648
    { "ng", "-"        , 1 },
 
1649
    { "nt", "!"        , 1 },
 
1650
    { "nw", " new"     , 1 },
 
1651
    { "oR", "|="       , 2 },
 
1652
    { "oo", "||"       , 2 },
 
1653
    { "or", "|"        , 2 },
 
1654
    { "pL", "+="       , 2 },
 
1655
    { "pl", "+"        , 2 },
 
1656
    { "pm", "->*"      , 2 },
 
1657
    { "pp", "++"       , 1 },
 
1658
    { "ps", "+"        , 1 },
 
1659
    { "pt", "->"       , 2 },
 
1660
    { "qu", "?"        , 3 },
 
1661
    { "rM", "%="       , 2 },
 
1662
    { "rS", ">>="      , 2 },
 
1663
    { "rm", "%"        , 2 },
 
1664
    { "rs", ">>"       , 2 },
 
1665
    { "sz", " sizeof"  , 1 }
 
1666
  };
 
1667
 
 
1668
  const int num_operators = 
 
1669
    sizeof (operators) / sizeof (struct operator_code);
 
1670
 
 
1671
  int c0 = next_char (dm);
 
1672
  int c1 = next_char (dm);
 
1673
  const struct operator_code* p1 = operators;
 
1674
  const struct operator_code* p2 = operators + num_operators;
 
1675
 
 
1676
  DEMANGLE_TRACE ("operator-name", dm);
 
1677
 
 
1678
  /* Assume the first argument is not a type.  */
 
1679
  if (type_arg)
 
1680
    *type_arg = 0;
 
1681
 
 
1682
  /* Is this a vendor-extended operator?  */
 
1683
  if (c0 == 'v' && IS_DIGIT (c1))
 
1684
    {
 
1685
      RETURN_IF_ERROR (result_add (dm, "operator "));
 
1686
      RETURN_IF_ERROR (demangle_source_name (dm));
 
1687
      *num_args = 0;
 
1688
      return STATUS_OK;
 
1689
    }
 
1690
 
 
1691
  /* Is this a conversion operator?  */
 
1692
  if (c0 == 'c' && c1 == 'v')
 
1693
    {
 
1694
      RETURN_IF_ERROR (result_add (dm, "operator "));
 
1695
      /* Demangle the converted-to type.  */
 
1696
      RETURN_IF_ERROR (demangle_type (dm));
 
1697
      *num_args = 0;
 
1698
      return STATUS_OK;
 
1699
    }
 
1700
 
 
1701
  /* Is it the sizeof variant that takes a type?  */
 
1702
  if (c0 == 's' && c1 == 't')
 
1703
    {
 
1704
      RETURN_IF_ERROR (result_add (dm, " sizeof"));
 
1705
      *num_args = 1;
 
1706
      if (type_arg)
 
1707
        *type_arg = 1;
 
1708
      return STATUS_OK;
 
1709
    }
 
1710
 
 
1711
  /* Perform a binary search for the operator code.  */
 
1712
  while (1)
 
1713
    {
 
1714
      const struct operator_code* p = p1 + (p2 - p1) / 2;
 
1715
      char match0 = p->code[0];
 
1716
      char match1 = p->code[1];
 
1717
 
 
1718
      if (c0 == match0 && c1 == match1)
 
1719
        /* Found it.  */
 
1720
        {
 
1721
          if (!short_name)
 
1722
            RETURN_IF_ERROR (result_add (dm, "operator"));
 
1723
          RETURN_IF_ERROR (result_add (dm, p->name));
 
1724
          *num_args = p->num_args;
 
1725
 
 
1726
          return STATUS_OK;
 
1727
        }
 
1728
 
 
1729
      if (p == p1)
 
1730
        /* Couldn't find it.  */
 
1731
        return "Unknown code in <operator-name>.";
 
1732
 
 
1733
      /* Try again.  */
 
1734
      if (c0 < match0 || (c0 == match0 && c1 < match1))
 
1735
        p2 = p;
 
1736
      else
 
1737
        p1 = p;
 
1738
    }
 
1739
}
 
1740
 
 
1741
/* Demangles and omits an <nv-offset>.
 
1742
 
 
1743
    <nv-offset> ::= <offset number>   # non-virtual base override  */
 
1744
 
 
1745
static status_t
 
1746
demangle_nv_offset (dm)
 
1747
     demangling_t dm;
 
1748
{
 
1749
  dyn_string_t number;
 
1750
  status_t status = STATUS_OK;
 
1751
 
 
1752
  DEMANGLE_TRACE ("h-offset", dm);
 
1753
 
 
1754
  /* Demangle the offset.  */
 
1755
  number = dyn_string_new (4);
 
1756
  if (number == NULL)
 
1757
    return STATUS_ALLOCATION_FAILED;
 
1758
  demangle_number_literally (dm, number, 10, 1);
 
1759
 
 
1760
  /* Don't display the offset unless in verbose mode.  */
 
1761
  if (flag_verbose)
 
1762
    {
 
1763
      status = result_add (dm, " [nv:");
 
1764
      if (STATUS_NO_ERROR (status))
 
1765
        status = result_add_string (dm, number);
 
1766
      if (STATUS_NO_ERROR (status))
 
1767
        status = result_add_char (dm, ']');
 
1768
    }
 
1769
 
 
1770
  /* Clean up.  */
 
1771
  dyn_string_delete (number);
 
1772
  RETURN_IF_ERROR (status);
 
1773
  return STATUS_OK;
 
1774
}
 
1775
 
 
1776
/* Demangles and emits a <v-offset>. 
 
1777
 
 
1778
    <v-offset>  ::= <offset number> _ <virtual offset number>
 
1779
                        # virtual base override, with vcall offset  */
 
1780
 
 
1781
static status_t
 
1782
demangle_v_offset (dm)
 
1783
     demangling_t dm;
 
1784
{
 
1785
  dyn_string_t number;
 
1786
  status_t status = STATUS_OK;
 
1787
 
 
1788
  DEMANGLE_TRACE ("v-offset", dm);
 
1789
 
 
1790
  /* Demangle the offset.  */
 
1791
  number = dyn_string_new (4);
 
1792
  if (number == NULL)
 
1793
    return STATUS_ALLOCATION_FAILED;
 
1794
  demangle_number_literally (dm, number, 10, 1);
 
1795
 
 
1796
  /* Don't display the offset unless in verbose mode.  */
 
1797
  if (flag_verbose)
 
1798
    {
 
1799
      status = result_add (dm, " [v:");
 
1800
      if (STATUS_NO_ERROR (status))
 
1801
        status = result_add_string (dm, number);
 
1802
      if (STATUS_NO_ERROR (status))
 
1803
        result_add_char (dm, ',');
 
1804
    }
 
1805
  dyn_string_delete (number);
 
1806
  RETURN_IF_ERROR (status);
 
1807
 
 
1808
  /* Demangle the separator.  */
 
1809
  RETURN_IF_ERROR (demangle_char (dm, '_'));
 
1810
 
 
1811
  /* Demangle the vcall offset.  */
 
1812
  number = dyn_string_new (4);
 
1813
  if (number == NULL)
 
1814
    return STATUS_ALLOCATION_FAILED;
 
1815
  demangle_number_literally (dm, number, 10, 1);
 
1816
 
 
1817
  /* Don't display the vcall offset unless in verbose mode.  */
 
1818
  if (flag_verbose)
 
1819
    {
 
1820
      status = result_add_string (dm, number);
 
1821
      if (STATUS_NO_ERROR (status))
 
1822
        status = result_add_char (dm, ']');
 
1823
    }
 
1824
  dyn_string_delete (number);
 
1825
  RETURN_IF_ERROR (status);
 
1826
 
 
1827
  return STATUS_OK;
 
1828
}
 
1829
 
 
1830
/* Demangles and emits a <call-offset>.
 
1831
 
 
1832
    <call-offset> ::= h <nv-offset> _
 
1833
                  ::= v <v-offset> _  */
 
1834
 
 
1835
static status_t
 
1836
demangle_call_offset (dm)
 
1837
     demangling_t dm;
 
1838
{
 
1839
  DEMANGLE_TRACE ("call-offset", dm);
 
1840
 
 
1841
  switch (peek_char (dm))
 
1842
    {
 
1843
    case 'h':
 
1844
      advance_char (dm);
 
1845
      /* Demangle the offset.  */
 
1846
      RETURN_IF_ERROR (demangle_nv_offset (dm));
 
1847
      /* Demangle the separator.  */
 
1848
      RETURN_IF_ERROR (demangle_char (dm, '_'));
 
1849
      break;
 
1850
 
 
1851
    case 'v':
 
1852
      advance_char (dm);
 
1853
      /* Demangle the offset.  */
 
1854
      RETURN_IF_ERROR (demangle_v_offset (dm));
 
1855
      /* Demangle the separator.  */
 
1856
      RETURN_IF_ERROR (demangle_char (dm, '_'));
 
1857
      break;
 
1858
 
 
1859
    default:
 
1860
      return "Unrecognized <call-offset>.";
 
1861
    }
 
1862
 
 
1863
  return STATUS_OK;
 
1864
}
 
1865
 
 
1866
/* Demangles and emits a <special-name>.  
 
1867
 
 
1868
    <special-name> ::= GV <object name>   # Guard variable
 
1869
                   ::= TV <type>          # virtual table
 
1870
                   ::= TT <type>          # VTT
 
1871
                   ::= TI <type>          # typeinfo structure
 
1872
                   ::= TS <type>          # typeinfo name  
 
1873
 
 
1874
   Other relevant productions include thunks:
 
1875
 
 
1876
    <special-name> ::= T <call-offset> <base encoding>
 
1877
                         # base is the nominal target function of thunk
 
1878
 
 
1879
    <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
 
1880
                         # base is the nominal target function of thunk
 
1881
                         # first call-offset is 'this' adjustment
 
1882
                         # second call-offset is result adjustment
 
1883
 
 
1884
   where
 
1885
 
 
1886
    <call-offset>  ::= h <nv-offset> _
 
1887
                   ::= v <v-offset> _
 
1888
 
 
1889
   Also demangles the special g++ manglings,
 
1890
 
 
1891
    <special-name> ::= TC <type> <offset number> _ <base type>
 
1892
                                          # construction vtable
 
1893
                   ::= TF <type>          # typeinfo function (old ABI only)
 
1894
                   ::= TJ <type>          # java Class structure  */
 
1895
 
 
1896
static status_t
 
1897
demangle_special_name (dm)
 
1898
     demangling_t dm;
 
1899
{
 
1900
  dyn_string_t number;
 
1901
  int unused;
 
1902
  char peek = peek_char (dm);
 
1903
 
 
1904
  DEMANGLE_TRACE ("special-name", dm);
 
1905
 
 
1906
  if (peek == 'G')
 
1907
    {
 
1908
      /* Consume the G.  */
 
1909
      advance_char (dm);
 
1910
      switch (peek_char (dm))
 
1911
        {
 
1912
        case 'V':
 
1913
          /* A guard variable name.  */
 
1914
          advance_char (dm);
 
1915
          RETURN_IF_ERROR (result_add (dm, "guard variable for "));
 
1916
          RETURN_IF_ERROR (demangle_name (dm, &unused));
 
1917
          break;
 
1918
 
 
1919
        case 'R':
 
1920
          /* A reference temporary.  */
 
1921
          advance_char (dm);
 
1922
          RETURN_IF_ERROR (result_add (dm, "reference temporary for "));
 
1923
          RETURN_IF_ERROR (demangle_name (dm, &unused));
 
1924
          break;
 
1925
          
 
1926
        default:
 
1927
          return "Unrecognized <special-name>.";
 
1928
        }
 
1929
    }
 
1930
  else if (peek == 'T')
 
1931
    {
 
1932
      status_t status = STATUS_OK;
 
1933
 
 
1934
      /* Other C++ implementation miscellania.  Consume the T.  */
 
1935
      advance_char (dm);
 
1936
 
 
1937
      switch (peek_char (dm))
 
1938
        {
 
1939
        case 'V':
 
1940
          /* Virtual table.  */
 
1941
          advance_char (dm);
 
1942
          RETURN_IF_ERROR (result_add (dm, "vtable for "));
 
1943
          RETURN_IF_ERROR (demangle_type (dm));
 
1944
          break;
 
1945
 
 
1946
        case 'T':
 
1947
          /* VTT structure.  */
 
1948
          advance_char (dm);
 
1949
          RETURN_IF_ERROR (result_add (dm, "VTT for "));
 
1950
          RETURN_IF_ERROR (demangle_type (dm));
 
1951
          break;
 
1952
 
 
1953
        case 'I':
 
1954
          /* Typeinfo structure.  */
 
1955
          advance_char (dm);
 
1956
          RETURN_IF_ERROR (result_add (dm, "typeinfo for "));
 
1957
          RETURN_IF_ERROR (demangle_type (dm));
 
1958
          break;
 
1959
 
 
1960
        case 'F':
 
1961
          /* Typeinfo function.  Used only in old ABI with new mangling.  */
 
1962
          advance_char (dm);
 
1963
          RETURN_IF_ERROR (result_add (dm, "typeinfo fn for "));
 
1964
          RETURN_IF_ERROR (demangle_type (dm));
 
1965
          break;
 
1966
 
 
1967
        case 'S':
 
1968
          /* Character string containing type name, used in typeinfo. */
 
1969
          advance_char (dm);
 
1970
          RETURN_IF_ERROR (result_add (dm, "typeinfo name for "));
 
1971
          RETURN_IF_ERROR (demangle_type (dm));
 
1972
          break;
 
1973
 
 
1974
        case 'J':
 
1975
          /* The java Class variable corresponding to a C++ class.  */
 
1976
          advance_char (dm);
 
1977
          RETURN_IF_ERROR (result_add (dm, "java Class for "));
 
1978
          RETURN_IF_ERROR (demangle_type (dm));
 
1979
          break;
 
1980
 
 
1981
        case 'h':
 
1982
          /* Non-virtual thunk.  */
 
1983
          advance_char (dm);
 
1984
          RETURN_IF_ERROR (result_add (dm, "non-virtual thunk"));
 
1985
          RETURN_IF_ERROR (demangle_nv_offset (dm));
 
1986
          /* Demangle the separator.  */
 
1987
          RETURN_IF_ERROR (demangle_char (dm, '_'));
 
1988
          /* Demangle and emit the target name and function type.  */
 
1989
          RETURN_IF_ERROR (result_add (dm, " to "));
 
1990
          RETURN_IF_ERROR (demangle_encoding (dm));
 
1991
          break;
 
1992
 
 
1993
        case 'v':
 
1994
          /* Virtual thunk.  */
 
1995
          advance_char (dm);
 
1996
          RETURN_IF_ERROR (result_add (dm, "virtual thunk"));
 
1997
          RETURN_IF_ERROR (demangle_v_offset (dm));
 
1998
          /* Demangle the separator.  */
 
1999
          RETURN_IF_ERROR (demangle_char (dm, '_'));
 
2000
          /* Demangle and emit the target function.  */
 
2001
          RETURN_IF_ERROR (result_add (dm, " to "));
 
2002
          RETURN_IF_ERROR (demangle_encoding (dm));
 
2003
          break;
 
2004
 
 
2005
        case 'c':
 
2006
          /* Covariant return thunk.  */
 
2007
          advance_char (dm);
 
2008
          RETURN_IF_ERROR (result_add (dm, "covariant return thunk"));
 
2009
          RETURN_IF_ERROR (demangle_call_offset (dm));
 
2010
          RETURN_IF_ERROR (demangle_call_offset (dm));
 
2011
          /* Demangle and emit the target function.  */
 
2012
          RETURN_IF_ERROR (result_add (dm, " to "));
 
2013
          RETURN_IF_ERROR (demangle_encoding (dm));
 
2014
          break;
 
2015
 
 
2016
        case 'C':
 
2017
          /* TC is a special g++ mangling for a construction vtable. */
 
2018
          if (!flag_strict)
 
2019
            {
 
2020
              dyn_string_t derived_type;
 
2021
 
 
2022
              advance_char (dm);
 
2023
              RETURN_IF_ERROR (result_add (dm, "construction vtable for "));
 
2024
 
 
2025
              /* Demangle the derived type off to the side.  */
 
2026
              RETURN_IF_ERROR (result_push (dm));
 
2027
              RETURN_IF_ERROR (demangle_type (dm));
 
2028
              derived_type = (dyn_string_t) result_pop (dm);
 
2029
 
 
2030
              /* Demangle the offset.  */
 
2031
              number = dyn_string_new (4);
 
2032
              if (number == NULL)
 
2033
                {
 
2034
                  dyn_string_delete (derived_type);
 
2035
                  return STATUS_ALLOCATION_FAILED;
 
2036
                }
 
2037
              demangle_number_literally (dm, number, 10, 1);
 
2038
              /* Demangle the underscore separator.  */
 
2039
              status = demangle_char (dm, '_');
 
2040
 
 
2041
              /* Demangle the base type.  */
 
2042
              if (STATUS_NO_ERROR (status))
 
2043
                status = demangle_type (dm);
 
2044
 
 
2045
              /* Emit the derived type.  */
 
2046
              if (STATUS_NO_ERROR (status))
 
2047
                status = result_add (dm, "-in-");
 
2048
              if (STATUS_NO_ERROR (status))
 
2049
                status = result_add_string (dm, derived_type);
 
2050
              dyn_string_delete (derived_type);
 
2051
 
 
2052
              /* Don't display the offset unless in verbose mode.  */
 
2053
              if (flag_verbose)
 
2054
                {
 
2055
                  status = result_add_char (dm, ' ');
 
2056
                  if (STATUS_NO_ERROR (status))
 
2057
                    result_add_string (dm, number);
 
2058
                }
 
2059
              dyn_string_delete (number);
 
2060
              RETURN_IF_ERROR (status);
 
2061
              break;
 
2062
            }
 
2063
          /* If flag_strict, fall through.  */
 
2064
 
 
2065
        default:
 
2066
          return "Unrecognized <special-name>.";
 
2067
        }
 
2068
    }
 
2069
  else
 
2070
    return STATUS_ERROR;
 
2071
 
 
2072
  return STATUS_OK;
 
2073
}
 
2074
 
 
2075
/* Demangles and emits a <ctor-dtor-name>.  
 
2076
   
 
2077
    <ctor-dtor-name>
 
2078
                   ::= C1  # complete object (in-charge) ctor
 
2079
                   ::= C2  # base object (not-in-charge) ctor
 
2080
                   ::= C3  # complete object (in-charge) allocating ctor
 
2081
                   ::= D0  # deleting (in-charge) dtor
 
2082
                   ::= D1  # complete object (in-charge) dtor
 
2083
                   ::= D2  # base object (not-in-charge) dtor  */
 
2084
 
 
2085
static status_t
 
2086
demangle_ctor_dtor_name (dm)
 
2087
     demangling_t dm;
 
2088
{
 
2089
  static const char *const ctor_flavors[] = 
 
2090
  {
 
2091
    "in-charge",
 
2092
    "not-in-charge",
 
2093
    "allocating"
 
2094
  };
 
2095
  static const char *const dtor_flavors[] = 
 
2096
  {
 
2097
    "in-charge deleting",
 
2098
    "in-charge",
 
2099
    "not-in-charge"
 
2100
  };
 
2101
 
 
2102
  int flavor;
 
2103
  char peek = peek_char (dm);
 
2104
 
 
2105
  DEMANGLE_TRACE ("ctor-dtor-name", dm);
 
2106
  
 
2107
  if (peek == 'C')
 
2108
    {
 
2109
      /* A constructor name.  Consume the C.  */
 
2110
      advance_char (dm);
 
2111
      flavor = next_char (dm);
 
2112
      if (flavor < '1' || flavor > '3')
 
2113
        return "Unrecognized constructor.";
 
2114
      RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
 
2115
      switch (flavor)
 
2116
        {
 
2117
        case '1': dm->is_constructor = gnu_v3_complete_object_ctor;
 
2118
          break;
 
2119
        case '2': dm->is_constructor = gnu_v3_base_object_ctor;
 
2120
          break;
 
2121
        case '3': dm->is_constructor = gnu_v3_complete_object_allocating_ctor;
 
2122
          break;
 
2123
        }
 
2124
      /* Print the flavor of the constructor if in verbose mode.  */
 
2125
      if (flag_verbose)
 
2126
        {
 
2127
          RETURN_IF_ERROR (result_add (dm, "["));
 
2128
          RETURN_IF_ERROR (result_add (dm, ctor_flavors[flavor - '1']));
 
2129
          RETURN_IF_ERROR (result_add_char (dm, ']'));
 
2130
        }
 
2131
    }
 
2132
  else if (peek == 'D')
 
2133
    {
 
2134
      /* A destructor name.  Consume the D.  */
 
2135
      advance_char (dm);
 
2136
      flavor = next_char (dm);
 
2137
      if (flavor < '0' || flavor > '2')
 
2138
        return "Unrecognized destructor.";
 
2139
      RETURN_IF_ERROR (result_add_char (dm, '~'));
 
2140
      RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
 
2141
      switch (flavor)
 
2142
        {
 
2143
        case '0': dm->is_destructor = gnu_v3_deleting_dtor;
 
2144
          break;
 
2145
        case '1': dm->is_destructor = gnu_v3_complete_object_dtor;
 
2146
          break;
 
2147
        case '2': dm->is_destructor = gnu_v3_base_object_dtor;
 
2148
          break;
 
2149
        }
 
2150
      /* Print the flavor of the destructor if in verbose mode.  */
 
2151
      if (flag_verbose)
 
2152
        {
 
2153
          RETURN_IF_ERROR (result_add (dm, " ["));
 
2154
          RETURN_IF_ERROR (result_add (dm, dtor_flavors[flavor - '0']));
 
2155
          RETURN_IF_ERROR (result_add_char (dm, ']'));
 
2156
        }
 
2157
    }
 
2158
  else
 
2159
    return STATUS_ERROR;
 
2160
 
 
2161
  return STATUS_OK;
 
2162
}
 
2163
 
 
2164
/* Handle pointer, reference, and pointer-to-member cases for
 
2165
   demangle_type.  All consecutive `P's, `R's, and 'M's are joined to
 
2166
   build a pointer/reference type.  We snarf all these, plus the
 
2167
   following <type>, all at once since we need to know whether we have
 
2168
   a pointer to data or pointer to function to construct the right
 
2169
   output syntax.  C++'s pointer syntax is hairy.  
 
2170
 
 
2171
   This function adds substitution candidates for every nested
 
2172
   pointer/reference type it processes, including the outermost, final
 
2173
   type, assuming the substitution starts at SUBSTITUTION_START in the
 
2174
   demangling result.  For example, if this function demangles
 
2175
   `PP3Foo', it will add a substitution for `Foo', `Foo*', and
 
2176
   `Foo**', in that order.
 
2177
 
 
2178
   *INSERT_POS is a quantity used internally, when this function calls
 
2179
   itself recursively, to figure out where to insert pointer
 
2180
   punctuation on the way up.  On entry to this function, INSERT_POS
 
2181
   should point to a temporary value, but that value need not be
 
2182
   initialized.
 
2183
 
 
2184
     <type> ::= P <type>
 
2185
            ::= R <type>
 
2186
            ::= <pointer-to-member-type>
 
2187
 
 
2188
     <pointer-to-member-type> ::= M </class/ type> </member/ type>  */
 
2189
 
 
2190
static status_t
 
2191
demangle_type_ptr (dm, insert_pos, substitution_start)
 
2192
     demangling_t dm;
 
2193
     int *insert_pos;
 
2194
     int substitution_start;
 
2195
{
 
2196
  status_t status;
 
2197
  int is_substitution_candidate = 1;
 
2198
 
 
2199
  DEMANGLE_TRACE ("type*", dm);
 
2200
 
 
2201
  /* Scan forward, collecting pointers and references into symbols,
 
2202
     until we hit something else.  Then emit the type.  */
 
2203
  switch (peek_char (dm))
 
2204
    {
 
2205
    case 'P':
 
2206
      /* A pointer.  Snarf the `P'.  */
 
2207
      advance_char (dm);
 
2208
      /* Demangle the underlying type.  */
 
2209
      RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos, 
 
2210
                                          substitution_start));
 
2211
      /* Insert an asterisk where we're told to; it doesn't
 
2212
         necessarily go at the end.  If we're doing Java style output, 
 
2213
         there is no pointer symbol.  */
 
2214
      if (dm->style != DMGL_JAVA)
 
2215
        RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '*'));
 
2216
      /* The next (outermost) pointer or reference character should go
 
2217
         after this one.  */
 
2218
      ++(*insert_pos);
 
2219
      break;
 
2220
 
 
2221
    case 'R':
 
2222
      /* A reference.  Snarf the `R'.  */
 
2223
      advance_char (dm);
 
2224
      /* Demangle the underlying type.  */
 
2225
      RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos, 
 
2226
                                          substitution_start));
 
2227
      /* Insert an ampersand where we're told to; it doesn't
 
2228
         necessarily go at the end.  */
 
2229
      RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '&'));
 
2230
      /* The next (outermost) pointer or reference character should go
 
2231
         after this one.  */
 
2232
      ++(*insert_pos);
 
2233
      break;
 
2234
 
 
2235
    case 'M':
 
2236
    {
 
2237
      /* A pointer-to-member.  */
 
2238
      dyn_string_t class_type;
 
2239
      
 
2240
      /* Eat the 'M'.  */
 
2241
      advance_char (dm);
 
2242
      
 
2243
      /* Capture the type of which this is a pointer-to-member.  */
 
2244
      RETURN_IF_ERROR (result_push (dm));
 
2245
      RETURN_IF_ERROR (demangle_type (dm));
 
2246
      class_type = (dyn_string_t) result_pop (dm);
 
2247
      
 
2248
      if (peek_char (dm) == 'F')
 
2249
        /* A pointer-to-member function.  We want output along the
 
2250
           lines of `void (C::*) (int, int)'.  Demangle the function
 
2251
           type, which would in this case give `void () (int, int)'
 
2252
           and set *insert_pos to the spot between the first
 
2253
           parentheses.  */
 
2254
        status = demangle_type_ptr (dm, insert_pos, substitution_start);
 
2255
      else if (peek_char (dm) == 'A')
 
2256
        /* A pointer-to-member array variable.  We want output that
 
2257
           looks like `int (Klass::*) [10]'.  Demangle the array type
 
2258
           as `int () [10]', and set *insert_pos to the spot between
 
2259
           the parentheses.  */
 
2260
        status = demangle_array_type (dm, insert_pos);
 
2261
      else
 
2262
        {
 
2263
          /* A pointer-to-member variable.  Demangle the type of the
 
2264
             pointed-to member.  */
 
2265
          status = demangle_type (dm);
 
2266
          /* Make it pretty.  */
 
2267
          if (STATUS_NO_ERROR (status)
 
2268
              && !result_previous_char_is_space (dm))
 
2269
            status = result_add_char (dm, ' ');
 
2270
          /* The pointer-to-member notation (e.g. `C::*') follows the
 
2271
             member's type.  */
 
2272
          *insert_pos = result_caret_pos (dm);
 
2273
        }
 
2274
 
 
2275
      /* Build the pointer-to-member notation.  */
 
2276
      if (STATUS_NO_ERROR (status))
 
2277
        status = result_insert (dm, *insert_pos, "::*");
 
2278
      if (STATUS_NO_ERROR (status))
 
2279
        status = result_insert_string (dm, *insert_pos, class_type);
 
2280
      /* There may be additional levels of (pointer or reference)
 
2281
         indirection in this type.  If so, the `*' and `&' should be
 
2282
         added after the pointer-to-member notation (e.g. `C::*&' for
 
2283
         a reference to a pointer-to-member of class C).  */
 
2284
      *insert_pos += dyn_string_length (class_type) + 3;
 
2285
 
 
2286
      /* Clean up. */
 
2287
      dyn_string_delete (class_type);
 
2288
 
 
2289
      RETURN_IF_ERROR (status);
 
2290
    }
 
2291
    break;
 
2292
 
 
2293
    case 'F':
 
2294
      /* Ooh, tricky, a pointer-to-function.  When we demangle the
 
2295
         function type, the return type should go at the very
 
2296
         beginning.  */
 
2297
      *insert_pos = result_caret_pos (dm);
 
2298
      /* The parentheses indicate this is a function pointer or
 
2299
         reference type.  */
 
2300
      RETURN_IF_ERROR (result_add (dm, "()"));
 
2301
      /* Now demangle the function type.  The return type will be
 
2302
         inserted before the `()', and the argument list will go after
 
2303
         it.  */
 
2304
      RETURN_IF_ERROR (demangle_function_type (dm, insert_pos));
 
2305
      /* We should now have something along the lines of 
 
2306
         `void () (int, int)'.  The pointer or reference characters
 
2307
         have to inside the first set of parentheses.  *insert_pos has
 
2308
         already been updated to point past the end of the return
 
2309
         type.  Move it one character over so it points inside the
 
2310
         `()'.  */
 
2311
      ++(*insert_pos);
 
2312
      break;
 
2313
 
 
2314
    case 'A':
 
2315
      /* An array pointer or reference.  demangle_array_type will figure
 
2316
         out where the asterisks and ampersands go.  */
 
2317
      RETURN_IF_ERROR (demangle_array_type (dm, insert_pos));
 
2318
      break;
 
2319
 
 
2320
    default:
 
2321
      /* No more pointer or reference tokens; this is therefore a
 
2322
         pointer to data.  Finish up by demangling the underlying
 
2323
         type.  */
 
2324
      RETURN_IF_ERROR (demangle_type (dm));
 
2325
      /* The pointer or reference characters follow the underlying
 
2326
         type, as in `int*&'.  */
 
2327
      *insert_pos = result_caret_pos (dm);
 
2328
      /* Because of the production <type> ::= <substitution>,
 
2329
         demangle_type will already have added the underlying type as
 
2330
         a substitution candidate.  Don't do it again.  */
 
2331
      is_substitution_candidate = 0;
 
2332
      break;
 
2333
    }
 
2334
  
 
2335
  if (is_substitution_candidate)
 
2336
    RETURN_IF_ERROR (substitution_add (dm, substitution_start, 0));
 
2337
  
 
2338
  return STATUS_OK;
 
2339
}
 
2340
 
 
2341
/* Demangles and emits a <type>.  
 
2342
 
 
2343
    <type> ::= <builtin-type>
 
2344
           ::= <function-type>
 
2345
           ::= <class-enum-type>
 
2346
           ::= <array-type>
 
2347
           ::= <pointer-to-member-type>
 
2348
           ::= <template-param>
 
2349
           ::= <template-template-param> <template-args>
 
2350
           ::= <CV-qualifiers> <type>
 
2351
           ::= P <type>   # pointer-to
 
2352
           ::= R <type>   # reference-to
 
2353
           ::= C <type>   # complex pair (C 2000)
 
2354
           ::= G <type>   # imaginary (C 2000)
 
2355
           ::= U <source-name> <type>     # vendor extended type qualifier
 
2356
           ::= <substitution>  */
 
2357
 
 
2358
static status_t
 
2359
demangle_type (dm)
 
2360
     demangling_t dm;
 
2361
{
 
2362
  int start = substitution_start (dm);
 
2363
  char peek = peek_char (dm);
 
2364
  char peek_next;
 
2365
  int encode_return_type = 0;
 
2366
  template_arg_list_t old_arg_list = current_template_arg_list (dm);
 
2367
  int insert_pos;
 
2368
 
 
2369
  /* A <type> can be a <substitution>; therefore, this <type> is a
 
2370
     substitution candidate unless a special condition holds (see
 
2371
     below).  */
 
2372
  int is_substitution_candidate = 1;
 
2373
 
 
2374
  DEMANGLE_TRACE ("type", dm);
 
2375
 
 
2376
  /* A <class-enum-type> can start with a digit (a <source-name>), an
 
2377
     N (a <nested-name>), or a Z (a <local-name>).  */
 
2378
  if (IS_DIGIT ((unsigned char) peek) || peek == 'N' || peek == 'Z')
 
2379
    RETURN_IF_ERROR (demangle_class_enum_type (dm, &encode_return_type));
 
2380
  /* Lower-case letters begin <builtin-type>s, except for `r', which
 
2381
     denotes restrict.  */
 
2382
  else if (peek >= 'a' && peek <= 'z' && peek != 'r')
 
2383
    {
 
2384
      RETURN_IF_ERROR (demangle_builtin_type (dm));
 
2385
      /* Built-in types are not substitution candidates.  */
 
2386
      is_substitution_candidate = 0;
 
2387
    }
 
2388
  else
 
2389
    switch (peek)
 
2390
      {
 
2391
      case 'r':
 
2392
      case 'V':
 
2393
      case 'K':
 
2394
        /* CV-qualifiers (including restrict).  We have to demangle
 
2395
           them off to the side, since C++ syntax puts them in a funny
 
2396
           place for qualified pointer and reference types.  */
 
2397
        {
 
2398
          status_t status;
 
2399
          dyn_string_t cv_qualifiers = dyn_string_new (24);
 
2400
          int old_caret_position = result_get_caret (dm);
 
2401
 
 
2402
          if (cv_qualifiers == NULL)
 
2403
            return STATUS_ALLOCATION_FAILED;
 
2404
 
 
2405
          /* Decode all adjacent CV qualifiers.  */
 
2406
          demangle_CV_qualifiers (dm, cv_qualifiers);
 
2407
          /* Emit them, and shift the caret left so that the
 
2408
             underlying type will be emitted before the qualifiers.  */
 
2409
          status = result_add_string (dm, cv_qualifiers);
 
2410
          result_shift_caret (dm, -dyn_string_length (cv_qualifiers));
 
2411
          /* Clean up.  */
 
2412
          dyn_string_delete (cv_qualifiers);
 
2413
          RETURN_IF_ERROR (status);
 
2414
          /* Also prepend a blank, if needed.  */
 
2415
          RETURN_IF_ERROR (result_add_char (dm, ' '));
 
2416
          result_shift_caret (dm, -1);
 
2417
 
 
2418
          /* Demangle the underlying type.  It will be emitted before
 
2419
             the CV qualifiers, since we moved the caret.  */
 
2420
          RETURN_IF_ERROR (demangle_type (dm));
 
2421
 
 
2422
          /* Put the caret back where it was previously.  */
 
2423
          result_set_caret (dm, old_caret_position);
 
2424
        }
 
2425
        break;
 
2426
 
 
2427
      case 'F':
 
2428
        return "Non-pointer or -reference function type.";
 
2429
 
 
2430
      case 'A':
 
2431
        RETURN_IF_ERROR (demangle_array_type (dm, NULL));
 
2432
        break;
 
2433
 
 
2434
      case 'T':
 
2435
        /* It's either a <template-param> or a
 
2436
           <template-template-param>.  In either case, demangle the
 
2437
           `T' token first.  */
 
2438
        RETURN_IF_ERROR (demangle_template_param (dm));
 
2439
 
 
2440
        /* Check for a template argument list; if one is found, it's a
 
2441
             <template-template-param> ::= <template-param>
 
2442
                                       ::= <substitution>  */
 
2443
        if (peek_char (dm) == 'I')
 
2444
          {
 
2445
            /* Add a substitution candidate.  The template parameter
 
2446
               `T' token is a substitution candidate by itself,
 
2447
               without the template argument list.  */
 
2448
            RETURN_IF_ERROR (substitution_add (dm, start, encode_return_type));
 
2449
 
 
2450
            /* Now demangle the template argument list.  */
 
2451
            RETURN_IF_ERROR (demangle_template_args (dm));
 
2452
            /* The entire type, including the template template
 
2453
               parameter and its argument list, will be added as a
 
2454
               substitution candidate below.  */
 
2455
          }
 
2456
 
 
2457
        break;
 
2458
 
 
2459
      case 'S':
 
2460
        /* First check if this is a special substitution.  If it is,
 
2461
           this is a <class-enum-type>.  Special substitutions have a
 
2462
           letter following the `S'; other substitutions have a digit
 
2463
           or underscore.  */
 
2464
        peek_next = peek_char_next (dm);
 
2465
        if (IS_DIGIT (peek_next) || peek_next == '_')
 
2466
          {
 
2467
            RETURN_IF_ERROR (demangle_substitution (dm, &encode_return_type));
 
2468
            
 
2469
            /* The substituted name may have been a template name.
 
2470
               Check if template arguments follow, and if so, demangle
 
2471
               them.  */
 
2472
            if (peek_char (dm) == 'I')
 
2473
              RETURN_IF_ERROR (demangle_template_args (dm));
 
2474
            else
 
2475
              /* A substitution token is not itself a substitution
 
2476
                 candidate.  (However, if the substituted template is
 
2477
                 instantiated, the resulting type is.)  */
 
2478
              is_substitution_candidate = 0;
 
2479
          }
 
2480
        else
 
2481
          {
 
2482
            /* Now some trickiness.  We have a special substitution
 
2483
               here.  Often, the special substitution provides the
 
2484
               name of a template that's subsequently instantiated,
 
2485
               for instance `SaIcE' => std::allocator<char>.  In these
 
2486
               cases we need to add a substitution candidate for the
 
2487
               entire <class-enum-type> and thus don't want to clear
 
2488
               the is_substitution_candidate flag.
 
2489
 
 
2490
               However, it's possible that what we have here is a
 
2491
               substitution token representing an entire type, such as
 
2492
               `Ss' => std::string.  In this case, we mustn't add a
 
2493
               new substitution candidate for this substitution token.
 
2494
               To detect this case, remember where the start of the
 
2495
               substitution token is.  */
 
2496
            const char *next = dm->next;
 
2497
            /* Now demangle the <class-enum-type>.  */
 
2498
            RETURN_IF_ERROR 
 
2499
              (demangle_class_enum_type (dm, &encode_return_type));
 
2500
            /* If all that was just demangled is the two-character
 
2501
               special substitution token, supress the addition of a
 
2502
               new candidate for it.  */
 
2503
            if (dm->next == next + 2)
 
2504
              is_substitution_candidate = 0;
 
2505
          }
 
2506
 
 
2507
        break;
 
2508
 
 
2509
      case 'P':
 
2510
      case 'R':
 
2511
      case 'M':
 
2512
        RETURN_IF_ERROR (demangle_type_ptr (dm, &insert_pos, start));
 
2513
        /* demangle_type_ptr adds all applicable substitution
 
2514
           candidates.  */
 
2515
        is_substitution_candidate = 0;
 
2516
        break;
 
2517
 
 
2518
      case 'C':
 
2519
        /* A C99 complex type.  */
 
2520
        RETURN_IF_ERROR (result_add (dm, "complex "));
 
2521
        advance_char (dm);
 
2522
        RETURN_IF_ERROR (demangle_type (dm));
 
2523
        break;
 
2524
 
 
2525
      case 'G':
 
2526
        /* A C99 imaginary type.  */
 
2527
        RETURN_IF_ERROR (result_add (dm, "imaginary "));
 
2528
        advance_char (dm);
 
2529
        RETURN_IF_ERROR (demangle_type (dm));
 
2530
        break;
 
2531
 
 
2532
      case 'U':
 
2533
        /* Vendor-extended type qualifier.  */
 
2534
        advance_char (dm);
 
2535
        RETURN_IF_ERROR (demangle_source_name (dm));
 
2536
        RETURN_IF_ERROR (result_add_char (dm, ' '));
 
2537
        RETURN_IF_ERROR (demangle_type (dm));
 
2538
        break;
 
2539
 
 
2540
      default:
 
2541
        return "Unexpected character in <type>.";
 
2542
      }
 
2543
 
 
2544
  if (is_substitution_candidate)
 
2545
    /* Add a new substitution for the type. If this type was a
 
2546
       <template-param>, pass its index since from the point of
 
2547
       substitutions; a <template-param> token is a substitution
 
2548
       candidate distinct from the type that is substituted for it.  */
 
2549
    RETURN_IF_ERROR (substitution_add (dm, start, encode_return_type));
 
2550
 
 
2551
  /* Pop off template argument lists added during mangling of this
 
2552
     type.  */
 
2553
  pop_to_template_arg_list (dm, old_arg_list);
 
2554
 
 
2555
  return STATUS_OK;
 
2556
}
 
2557
 
 
2558
/* C++ source names of builtin types, indexed by the mangled code
 
2559
   letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc).  */
 
2560
static const char *const builtin_type_names[26] = 
 
2561
{
 
2562
  "signed char",              /* a */
 
2563
  "bool",                     /* b */
 
2564
  "char",                     /* c */
 
2565
  "double",                   /* d */
 
2566
  "long double",              /* e */
 
2567
  "float",                    /* f */
 
2568
  "__float128",               /* g */
 
2569
  "unsigned char",            /* h */
 
2570
  "int",                      /* i */
 
2571
  "unsigned",                 /* j */
 
2572
  NULL,                       /* k */
 
2573
  "long",                     /* l */
 
2574
  "unsigned long",            /* m */
 
2575
  "__int128",                 /* n */
 
2576
  "unsigned __int128",        /* o */
 
2577
  NULL,                       /* p */
 
2578
  NULL,                       /* q */
 
2579
  NULL,                       /* r */
 
2580
  "short",                    /* s */
 
2581
  "unsigned short",           /* t */
 
2582
  NULL,                       /* u */
 
2583
  "void",                     /* v */
 
2584
  "wchar_t",                  /* w */
 
2585
  "long long",                /* x */
 
2586
  "unsigned long long",       /* y */
 
2587
  "..."                       /* z */
 
2588
};
 
2589
 
 
2590
/* Java source names of builtin types.  Types that arn't valid in Java
 
2591
   are also included here - we don't fail if someone attempts to demangle a 
 
2592
   C++ symbol in Java style. */
 
2593
static const char *const java_builtin_type_names[26] = 
 
2594
{
 
2595
  "signed char",                /* a */
 
2596
  "boolean", /* C++ "bool" */   /* b */
 
2597
  "byte", /* C++ "char" */      /* c */
 
2598
  "double",                     /* d */
 
2599
  "long double",                /* e */
 
2600
  "float",                      /* f */
 
2601
  "__float128",                 /* g */
 
2602
  "unsigned char",              /* h */
 
2603
  "int",                        /* i */
 
2604
  "unsigned",                   /* j */
 
2605
  NULL,                         /* k */
 
2606
  "long",                       /* l */
 
2607
  "unsigned long",              /* m */
 
2608
  "__int128",                   /* n */
 
2609
  "unsigned __int128",          /* o */
 
2610
  NULL,                         /* p */
 
2611
  NULL,                         /* q */
 
2612
  NULL,                         /* r */
 
2613
  "short",                      /* s */
 
2614
  "unsigned short",             /* t */
 
2615
  NULL,                         /* u */
 
2616
  "void",                       /* v */
 
2617
  "char", /* C++ "wchar_t" */   /* w */
 
2618
  "long", /* C++ "long long" */ /* x */
 
2619
  "unsigned long long",         /* y */
 
2620
  "..."                         /* z */
 
2621
};
 
2622
 
 
2623
/* Demangles and emits a <builtin-type>.  
 
2624
 
 
2625
    <builtin-type> ::= v  # void
 
2626
                   ::= w  # wchar_t
 
2627
                   ::= b  # bool
 
2628
                   ::= c  # char
 
2629
                   ::= a  # signed char
 
2630
                   ::= h  # unsigned char
 
2631
                   ::= s  # short
 
2632
                   ::= t  # unsigned short
 
2633
                   ::= i  # int
 
2634
                   ::= j  # unsigned int
 
2635
                   ::= l  # long
 
2636
                   ::= m  # unsigned long
 
2637
                   ::= x  # long long, __int64
 
2638
                   ::= y  # unsigned long long, __int64
 
2639
                   ::= n  # __int128
 
2640
                   ::= o  # unsigned __int128
 
2641
                   ::= f  # float
 
2642
                   ::= d  # double
 
2643
                   ::= e  # long double, __float80
 
2644
                   ::= g  # __float128
 
2645
                   ::= z  # ellipsis
 
2646
                   ::= u <source-name>    # vendor extended type  */
 
2647
 
 
2648
static status_t
 
2649
demangle_builtin_type (dm)
 
2650
     demangling_t dm;
 
2651
{
 
2652
 
 
2653
  char code = peek_char (dm);
 
2654
 
 
2655
  DEMANGLE_TRACE ("builtin-type", dm);
 
2656
 
 
2657
  if (code == 'u')
 
2658
    {
 
2659
      advance_char (dm);
 
2660
      RETURN_IF_ERROR (demangle_source_name (dm));
 
2661
      return STATUS_OK;
 
2662
    }
 
2663
  else if (code >= 'a' && code <= 'z')
 
2664
    {
 
2665
      const char *type_name;
 
2666
      /* Java uses different names for some built-in types. */
 
2667
      if (dm->style == DMGL_JAVA)
 
2668
        type_name = java_builtin_type_names[code - 'a'];
 
2669
      else
 
2670
        type_name = builtin_type_names[code - 'a'];
 
2671
      if (type_name == NULL)
 
2672
        return "Unrecognized <builtin-type> code.";
 
2673
 
 
2674
      RETURN_IF_ERROR (result_add (dm, type_name));
 
2675
      advance_char (dm);
 
2676
      return STATUS_OK;
 
2677
    }
 
2678
  else
 
2679
    return "Non-alphabetic <builtin-type> code.";
 
2680
}
 
2681
 
 
2682
/* Demangles all consecutive CV-qualifiers (const, volatile, and
 
2683
   restrict) at the current position.  The qualifiers are appended to
 
2684
   QUALIFIERS.  Returns STATUS_OK.  */
 
2685
 
 
2686
static status_t
 
2687
demangle_CV_qualifiers (dm, qualifiers)
 
2688
     demangling_t dm;
 
2689
     dyn_string_t qualifiers;
 
2690
{
 
2691
  DEMANGLE_TRACE ("CV-qualifiers", dm);
 
2692
 
 
2693
  while (1)
 
2694
    {
 
2695
      switch (peek_char (dm))
 
2696
        {
 
2697
        case 'r':
 
2698
          if (!dyn_string_append_space (qualifiers))
 
2699
            return STATUS_ALLOCATION_FAILED;
 
2700
          if (!dyn_string_append_cstr (qualifiers, "restrict"))
 
2701
            return STATUS_ALLOCATION_FAILED;
 
2702
          break;
 
2703
 
 
2704
        case 'V':
 
2705
          if (!dyn_string_append_space (qualifiers))
 
2706
            return STATUS_ALLOCATION_FAILED;
 
2707
          if (!dyn_string_append_cstr (qualifiers, "volatile"))
 
2708
            return STATUS_ALLOCATION_FAILED;
 
2709
          break;
 
2710
 
 
2711
        case 'K':
 
2712
          if (!dyn_string_append_space (qualifiers))
 
2713
            return STATUS_ALLOCATION_FAILED;
 
2714
          if (!dyn_string_append_cstr (qualifiers, "const"))
 
2715
            return STATUS_ALLOCATION_FAILED;
 
2716
          break;
 
2717
 
 
2718
        default:
 
2719
          return STATUS_OK;
 
2720
        }
 
2721
 
 
2722
      advance_char (dm);
 
2723
    }
 
2724
}
 
2725
 
 
2726
/* Demangles and emits a <function-type>.  *FUNCTION_NAME_POS is the
 
2727
   position in the result string of the start of the function
 
2728
   identifier, at which the function's return type will be inserted;
 
2729
   *FUNCTION_NAME_POS is updated to position past the end of the
 
2730
   function's return type.
 
2731
 
 
2732
    <function-type> ::= F [Y] <bare-function-type> E  */
 
2733
 
 
2734
static status_t
 
2735
demangle_function_type (dm, function_name_pos)
 
2736
     demangling_t dm;
 
2737
     int *function_name_pos;
 
2738
{
 
2739
  DEMANGLE_TRACE ("function-type", dm);
 
2740
  RETURN_IF_ERROR (demangle_char (dm, 'F'));  
 
2741
  if (peek_char (dm) == 'Y')
 
2742
    {
 
2743
      /* Indicate this function has C linkage if in verbose mode.  */
 
2744
      if (flag_verbose)
 
2745
        RETURN_IF_ERROR (result_add (dm, " [extern \"C\"] "));
 
2746
      advance_char (dm);
 
2747
    }
 
2748
  RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos));
 
2749
  RETURN_IF_ERROR (demangle_char (dm, 'E'));
 
2750
  return STATUS_OK;
 
2751
}
 
2752
 
 
2753
/* Demangles and emits a <bare-function-type>.  RETURN_TYPE_POS is the
 
2754
   position in the result string at which the function return type
 
2755
   should be inserted.  If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
 
2756
   function's return type is assumed not to be encoded.  
 
2757
 
 
2758
    <bare-function-type> ::= <signature type>+  */
 
2759
 
 
2760
static status_t
 
2761
demangle_bare_function_type (dm, return_type_pos)
 
2762
     demangling_t dm;
 
2763
     int *return_type_pos;
 
2764
{
 
2765
  /* Sequence is the index of the current function parameter, counting
 
2766
     from zero.  The value -1 denotes the return type.  */
 
2767
  int sequence = 
 
2768
    (return_type_pos == BFT_NO_RETURN_TYPE ? 0 : -1);
 
2769
 
 
2770
  DEMANGLE_TRACE ("bare-function-type", dm);
 
2771
 
 
2772
  RETURN_IF_ERROR (result_add_char (dm, '('));
 
2773
  while (!end_of_name_p (dm) && peek_char (dm) != 'E')
 
2774
    {
 
2775
      if (sequence == -1)
 
2776
        /* We're decoding the function's return type.  */
 
2777
        {
 
2778
          dyn_string_t return_type;
 
2779
          status_t status = STATUS_OK;
 
2780
 
 
2781
          /* Decode the return type off to the side.  */
 
2782
          RETURN_IF_ERROR (result_push (dm));
 
2783
          RETURN_IF_ERROR (demangle_type (dm));
 
2784
          return_type = (dyn_string_t) result_pop (dm);
 
2785
 
 
2786
          /* Add a space to the end of the type.  Insert the return
 
2787
             type where we've been asked to. */
 
2788
          if (!dyn_string_append_space (return_type))
 
2789
            status = STATUS_ALLOCATION_FAILED;
 
2790
          if (STATUS_NO_ERROR (status))
 
2791
            {
 
2792
              if (!dyn_string_insert (result_string (dm), *return_type_pos, 
 
2793
                                      return_type))
 
2794
                status = STATUS_ALLOCATION_FAILED;
 
2795
              else
 
2796
                *return_type_pos += dyn_string_length (return_type);
 
2797
            }
 
2798
 
 
2799
          dyn_string_delete (return_type);
 
2800
          RETURN_IF_ERROR (status);
 
2801
        }
 
2802
      else 
 
2803
        {
 
2804
          /* Skip `void' parameter types.  One should only occur as
 
2805
             the only type in a parameter list; in that case, we want
 
2806
             to print `foo ()' instead of `foo (void)'.  */
 
2807
          if (peek_char (dm) == 'v')
 
2808
            /* Consume the v.  */
 
2809
            advance_char (dm);
 
2810
          else
 
2811
            {
 
2812
              /* Separate parameter types by commas.  */
 
2813
              if (sequence > 0)
 
2814
                RETURN_IF_ERROR (result_add (dm, ", "));
 
2815
              /* Demangle the type.  */
 
2816
              RETURN_IF_ERROR (demangle_type (dm));
 
2817
            }
 
2818
        }
 
2819
 
 
2820
      ++sequence;
 
2821
    }
 
2822
  RETURN_IF_ERROR (result_add_char (dm, ')'));
 
2823
 
 
2824
  /* We should have demangled at least one parameter type (which would
 
2825
     be void, for a function that takes no parameters), plus the
 
2826
     return type, if we were supposed to demangle that.  */
 
2827
  if (sequence == -1)
 
2828
    return "Missing function return type.";
 
2829
  else if (sequence == 0)
 
2830
    return "Missing function parameter.";
 
2831
 
 
2832
  return STATUS_OK;
 
2833
}
 
2834
 
 
2835
/* Demangles and emits a <class-enum-type>.  *ENCODE_RETURN_TYPE is set to
 
2836
   non-zero if the type is a template-id, zero otherwise.  
 
2837
 
 
2838
    <class-enum-type> ::= <name>  */
 
2839
 
 
2840
static status_t
 
2841
demangle_class_enum_type (dm, encode_return_type)
 
2842
     demangling_t dm;
 
2843
     int *encode_return_type;
 
2844
{
 
2845
  DEMANGLE_TRACE ("class-enum-type", dm);
 
2846
 
 
2847
  RETURN_IF_ERROR (demangle_name (dm, encode_return_type));
 
2848
  return STATUS_OK;
 
2849
}
 
2850
 
 
2851
/* Demangles and emits an <array-type>.  
 
2852
 
 
2853
   If PTR_INSERT_POS is not NULL, the array type is formatted as a
 
2854
   pointer or reference to an array, except that asterisk and
 
2855
   ampersand punctuation is omitted (since it's not know at this
 
2856
   point).  *PTR_INSERT_POS is set to the position in the demangled
 
2857
   name at which this punctuation should be inserted.  For example,
 
2858
   `A10_i' is demangled to `int () [10]' and *PTR_INSERT_POS points
 
2859
   between the parentheses.
 
2860
 
 
2861
   If PTR_INSERT_POS is NULL, the array type is assumed not to be
 
2862
   pointer- or reference-qualified.  Then, for example, `A10_i' is
 
2863
   demangled simply as `int[10]'.  
 
2864
 
 
2865
    <array-type> ::= A [<dimension number>] _ <element type>  
 
2866
                 ::= A <dimension expression> _ <element type>  */
 
2867
 
 
2868
static status_t
 
2869
demangle_array_type (dm, ptr_insert_pos)
 
2870
     demangling_t dm;
 
2871
     int *ptr_insert_pos;
 
2872
{
 
2873
  status_t status = STATUS_OK;
 
2874
  dyn_string_t array_size = NULL;
 
2875
  char peek;
 
2876
 
 
2877
  DEMANGLE_TRACE ("array-type", dm);
 
2878
 
 
2879
  RETURN_IF_ERROR (demangle_char (dm, 'A'));
 
2880
 
 
2881
  /* Demangle the array size into array_size.  */
 
2882
  peek = peek_char (dm);
 
2883
  if (peek == '_')
 
2884
    /* Array bound is omitted.  This is a C99-style VLA.  */
 
2885
    ;
 
2886
  else if (IS_DIGIT (peek_char (dm))) 
 
2887
    {
 
2888
      /* It looks like a constant array bound.  */
 
2889
      array_size = dyn_string_new (10);
 
2890
      if (array_size == NULL)
 
2891
        return STATUS_ALLOCATION_FAILED;
 
2892
      status = demangle_number_literally (dm, array_size, 10, 0);
 
2893
    }
 
2894
  else
 
2895
    {
 
2896
      /* Anything is must be an expression for a nont-constant array
 
2897
         bound.  This happens if the array type occurs in a template
 
2898
         and the array bound references a template parameter.  */
 
2899
      RETURN_IF_ERROR (result_push (dm));
 
2900
      RETURN_IF_ERROR (demangle_expression (dm));
 
2901
      array_size = (dyn_string_t) result_pop (dm);
 
2902
    }
 
2903
  /* array_size may have been allocated by now, so we can't use
 
2904
     RETURN_IF_ERROR until it's been deallocated.  */
 
2905
 
 
2906
  /* Demangle the base type of the array.  */
 
2907
  if (STATUS_NO_ERROR (status))
 
2908
    status = demangle_char (dm, '_');
 
2909
  if (STATUS_NO_ERROR (status))
 
2910
    status = demangle_type (dm);
 
2911
 
 
2912
  if (ptr_insert_pos != NULL)
 
2913
    {
 
2914
      /* This array is actually part of an pointer- or
 
2915
         reference-to-array type.  Format appropriately, except we
 
2916
         don't know which and how much punctuation to use.  */
 
2917
      if (STATUS_NO_ERROR (status))
 
2918
        status = result_add (dm, " () ");
 
2919
      /* Let the caller know where to insert the punctuation.  */
 
2920
      *ptr_insert_pos = result_caret_pos (dm) - 2;
 
2921
    }
 
2922
 
 
2923
  /* Emit the array dimension syntax.  */
 
2924
  if (STATUS_NO_ERROR (status))
 
2925
    status = result_add_char (dm, '[');
 
2926
  if (STATUS_NO_ERROR (status) && array_size != NULL)
 
2927
    status = result_add_string (dm, array_size);
 
2928
  if (STATUS_NO_ERROR (status))
 
2929
    status = result_add_char (dm, ']');
 
2930
  if (array_size != NULL)
 
2931
    dyn_string_delete (array_size);
 
2932
  
 
2933
  RETURN_IF_ERROR (status);
 
2934
 
 
2935
  return STATUS_OK;
 
2936
}
 
2937
 
 
2938
/* Demangles and emits a <template-param>.  
 
2939
 
 
2940
    <template-param> ::= T_       # first template parameter
 
2941
                     ::= T <parameter-2 number> _  */
 
2942
 
 
2943
static status_t
 
2944
demangle_template_param (dm)
 
2945
     demangling_t dm;
 
2946
{
 
2947
  int parm_number;
 
2948
  template_arg_list_t current_arg_list = current_template_arg_list (dm);
 
2949
  string_list_t arg;
 
2950
 
 
2951
  DEMANGLE_TRACE ("template-param", dm);
 
2952
 
 
2953
  /* Make sure there is a template argmust list in which to look up
 
2954
     this parameter reference.  */
 
2955
  if (current_arg_list == NULL)
 
2956
    return "Template parameter outside of template.";
 
2957
 
 
2958
  RETURN_IF_ERROR (demangle_char (dm, 'T'));
 
2959
  if (peek_char (dm) == '_')
 
2960
    parm_number = 0;
 
2961
  else
 
2962
    {
 
2963
      RETURN_IF_ERROR (demangle_number (dm, &parm_number, 10, 0));
 
2964
      ++parm_number;
 
2965
    }
 
2966
  RETURN_IF_ERROR (demangle_char (dm, '_'));
 
2967
 
 
2968
  arg = template_arg_list_get_arg (current_arg_list, parm_number);
 
2969
  if (arg == NULL)
 
2970
    /* parm_number exceeded the number of arguments in the current
 
2971
       template argument list.  */
 
2972
    return "Template parameter number out of bounds.";
 
2973
  RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
 
2974
 
 
2975
  return STATUS_OK;
 
2976
}
 
2977
 
 
2978
/* Demangles and emits a <template-args>.  
 
2979
 
 
2980
    <template-args> ::= I <template-arg>+ E  */
 
2981
 
 
2982
static status_t
 
2983
demangle_template_args (dm)
 
2984
     demangling_t dm;
 
2985
{
 
2986
  int first = 1;
 
2987
  dyn_string_t old_last_source_name;
 
2988
  template_arg_list_t arg_list = template_arg_list_new ();
 
2989
 
 
2990
  if (arg_list == NULL)
 
2991
    return STATUS_ALLOCATION_FAILED;
 
2992
 
 
2993
  /* Preserve the most recently demangled source name.  */
 
2994
  old_last_source_name = dm->last_source_name;
 
2995
  dm->last_source_name = dyn_string_new (0);
 
2996
 
 
2997
  DEMANGLE_TRACE ("template-args", dm);
 
2998
 
 
2999
  if (dm->last_source_name == NULL)
 
3000
    return STATUS_ALLOCATION_FAILED;
 
3001
 
 
3002
  RETURN_IF_ERROR (demangle_char (dm, 'I'));
 
3003
  RETURN_IF_ERROR (result_open_template_list (dm));
 
3004
  do
 
3005
    {
 
3006
      string_list_t arg;
 
3007
 
 
3008
      if (first)
 
3009
        first = 0;
 
3010
      else
 
3011
        RETURN_IF_ERROR (result_add (dm, ", "));
 
3012
 
 
3013
      /* Capture the template arg.  */
 
3014
      RETURN_IF_ERROR (result_push (dm));
 
3015
      RETURN_IF_ERROR (demangle_template_arg (dm));
 
3016
      arg = result_pop (dm);
 
3017
 
 
3018
      /* Emit it in the demangled name.  */
 
3019
      RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
 
3020
 
 
3021
      /* Save it for use in expanding <template-param>s.  */
 
3022
      template_arg_list_add_arg (arg_list, arg);
 
3023
    }
 
3024
  while (peek_char (dm) != 'E');
 
3025
  /* Append the '>'.  */
 
3026
  RETURN_IF_ERROR (result_close_template_list (dm));
 
3027
 
 
3028
  /* Consume the 'E'.  */
 
3029
  advance_char (dm);
 
3030
 
 
3031
  /* Restore the most recent demangled source name.  */
 
3032
  dyn_string_delete (dm->last_source_name);
 
3033
  dm->last_source_name = old_last_source_name;
 
3034
 
 
3035
  /* Push the list onto the top of the stack of template argument
 
3036
     lists, so that arguments from it are used from now on when
 
3037
     expanding <template-param>s.  */
 
3038
  push_template_arg_list (dm, arg_list);
 
3039
 
 
3040
  return STATUS_OK;
 
3041
}
 
3042
 
 
3043
/* This function, which does not correspond to a production in the
 
3044
   mangling spec, handles the `literal' production for both
 
3045
   <template-arg> and <expr-primary>.  It does not expect or consume
 
3046
   the initial `L' or final `E'.  The demangling is given by:
 
3047
 
 
3048
     <literal> ::= <type> </value/ number>
 
3049
 
 
3050
   and the emitted output is `(type)number'.  */
 
3051
 
 
3052
static status_t
 
3053
demangle_literal (dm)
 
3054
     demangling_t dm;
 
3055
{
 
3056
  char peek = peek_char (dm);
 
3057
  dyn_string_t value_string;
 
3058
  status_t status;
 
3059
 
 
3060
  DEMANGLE_TRACE ("literal", dm);
 
3061
 
 
3062
  if (!flag_verbose && peek >= 'a' && peek <= 'z')
 
3063
    {
 
3064
      /* If not in verbose mode and this is a builtin type, see if we
 
3065
         can produce simpler numerical output.  In particular, for
 
3066
         integer types shorter than `long', just write the number
 
3067
         without type information; for bools, write `true' or `false'.
 
3068
         Other refinements could be made here too.  */
 
3069
 
 
3070
      /* This constant string is used to map from <builtin-type> codes
 
3071
         (26 letters of the alphabet) to codes that determine how the 
 
3072
         value will be displayed.  The codes are:
 
3073
           b: display as bool
 
3074
           i: display as int
 
3075
           l: display as long
 
3076
         A space means the value will be represented using cast
 
3077
         notation. */
 
3078
      static const char *const code_map = "ibi    iii ll     ii  i  ";
 
3079
 
 
3080
      char code = code_map[peek - 'a'];
 
3081
      /* FIXME: Implement demangling of floats and doubles.  */
 
3082
      if (code == 'u')
 
3083
        return STATUS_UNIMPLEMENTED;
 
3084
      if (code == 'b')
 
3085
        {
 
3086
          /* It's a boolean.  */
 
3087
          char value;
 
3088
 
 
3089
          /* Consume the b.  */
 
3090
          advance_char (dm);
 
3091
          /* Look at the next character.  It should be 0 or 1,
 
3092
             corresponding to false or true, respectively.  */
 
3093
          value = peek_char (dm);
 
3094
          if (value == '0')
 
3095
            RETURN_IF_ERROR (result_add (dm, "false"));
 
3096
          else if (value == '1')
 
3097
            RETURN_IF_ERROR (result_add (dm, "true"));
 
3098
          else
 
3099
            return "Unrecognized bool constant.";
 
3100
          /* Consume the 0 or 1.  */
 
3101
          advance_char (dm);
 
3102
          return STATUS_OK;
 
3103
        }
 
3104
      else if (code == 'i' || code == 'l')
 
3105
        {
 
3106
          /* It's an integer or long.  */
 
3107
 
 
3108
          /* Consume the type character.  */
 
3109
          advance_char (dm);
 
3110
 
 
3111
          /* Demangle the number and write it out.  */
 
3112
          value_string = dyn_string_new (0);
 
3113
          status = demangle_number_literally (dm, value_string, 10, 1);
 
3114
          if (STATUS_NO_ERROR (status))
 
3115
            status = result_add_string (dm, value_string);
 
3116
          /* For long integers, append an l.  */
 
3117
          if (code == 'l' && STATUS_NO_ERROR (status))
 
3118
            status = result_add_char (dm, code);
 
3119
          dyn_string_delete (value_string);
 
3120
 
 
3121
          RETURN_IF_ERROR (status);
 
3122
          return STATUS_OK;
 
3123
        }
 
3124
      /* ...else code == ' ', so fall through to represent this
 
3125
         literal's type explicitly using cast syntax.  */
 
3126
    }
 
3127
 
 
3128
  RETURN_IF_ERROR (result_add_char (dm, '('));
 
3129
  RETURN_IF_ERROR (demangle_type (dm));
 
3130
  RETURN_IF_ERROR (result_add_char (dm, ')'));
 
3131
 
 
3132
  value_string = dyn_string_new (0);
 
3133
  if (value_string == NULL)
 
3134
    return STATUS_ALLOCATION_FAILED;
 
3135
 
 
3136
  status = demangle_number_literally (dm, value_string, 10, 1);
 
3137
  if (STATUS_NO_ERROR (status))
 
3138
    status = result_add_string (dm, value_string);
 
3139
  dyn_string_delete (value_string);
 
3140
  RETURN_IF_ERROR (status);
 
3141
 
 
3142
  return STATUS_OK;
 
3143
}
 
3144
 
 
3145
/* Demangles and emits a <template-arg>.  
 
3146
 
 
3147
    <template-arg> ::= <type>                     # type
 
3148
                   ::= L <type> <value number> E  # literal
 
3149
                   ::= LZ <encoding> E            # external name
 
3150
                   ::= X <expression> E           # expression  */
 
3151
 
 
3152
static status_t
 
3153
demangle_template_arg (dm)
 
3154
     demangling_t dm;
 
3155
{
 
3156
  DEMANGLE_TRACE ("template-arg", dm);
 
3157
 
 
3158
  switch (peek_char (dm))
 
3159
    {
 
3160
    case 'L':
 
3161
      advance_char (dm);
 
3162
 
 
3163
      if (peek_char (dm) == 'Z')
 
3164
        {
 
3165
          /* External name.  */
 
3166
          advance_char (dm);
 
3167
          /* FIXME: Standard is contradictory here.  */
 
3168
          RETURN_IF_ERROR (demangle_encoding (dm));
 
3169
        }
 
3170
      else
 
3171
        RETURN_IF_ERROR (demangle_literal (dm));
 
3172
      RETURN_IF_ERROR (demangle_char (dm, 'E'));
 
3173
      break;
 
3174
 
 
3175
    case 'X':
 
3176
      /* Expression.  */
 
3177
      advance_char (dm);
 
3178
      RETURN_IF_ERROR (demangle_expression (dm));
 
3179
      RETURN_IF_ERROR (demangle_char (dm, 'E'));
 
3180
      break;
 
3181
 
 
3182
    default:
 
3183
      RETURN_IF_ERROR (demangle_type (dm));
 
3184
      break;
 
3185
    }
 
3186
 
 
3187
  return STATUS_OK;
 
3188
}
 
3189
 
 
3190
/* Demangles and emits an <expression>.
 
3191
 
 
3192
    <expression> ::= <unary operator-name> <expression>
 
3193
                 ::= <binary operator-name> <expression> <expression>
 
3194
                 ::= <expr-primary>  
 
3195
                 ::= <scope-expression>  */
 
3196
 
 
3197
static status_t
 
3198
demangle_expression (dm)
 
3199
     demangling_t dm;
 
3200
{
 
3201
  char peek = peek_char (dm);
 
3202
 
 
3203
  DEMANGLE_TRACE ("expression", dm);
 
3204
 
 
3205
  if (peek == 'L' || peek == 'T')
 
3206
    RETURN_IF_ERROR (demangle_expr_primary (dm));
 
3207
  else if (peek == 's' && peek_char_next (dm) == 'r')
 
3208
    RETURN_IF_ERROR (demangle_scope_expression (dm));
 
3209
  else
 
3210
    /* An operator expression.  */
 
3211
    {
 
3212
      int num_args;
 
3213
      int type_arg;
 
3214
      status_t status = STATUS_OK;
 
3215
      dyn_string_t operator_name;
 
3216
 
 
3217
      /* We have an operator name.  Since we want to output binary
 
3218
         operations in infix notation, capture the operator name
 
3219
         first.  */
 
3220
      RETURN_IF_ERROR (result_push (dm));
 
3221
      RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args,
 
3222
                                               &type_arg));
 
3223
      operator_name = (dyn_string_t) result_pop (dm);
 
3224
 
 
3225
      /* If it's binary, do an operand first.  */
 
3226
      if (num_args > 1)
 
3227
        {
 
3228
          status = result_add_char (dm, '(');
 
3229
          if (STATUS_NO_ERROR (status))
 
3230
            status = demangle_expression (dm);
 
3231
          if (STATUS_NO_ERROR (status))
 
3232
            status = result_add_char (dm, ')');
 
3233
        }
 
3234
 
 
3235
      /* Emit the operator.  */  
 
3236
      if (STATUS_NO_ERROR (status))
 
3237
        status = result_add_string (dm, operator_name);
 
3238
      dyn_string_delete (operator_name);
 
3239
      RETURN_IF_ERROR (status);
 
3240
      
 
3241
      /* Emit its second (if binary) or only (if unary) operand.  */
 
3242
      RETURN_IF_ERROR (result_add_char (dm, '('));
 
3243
      if (type_arg)
 
3244
        RETURN_IF_ERROR (demangle_type (dm));
 
3245
      else
 
3246
        RETURN_IF_ERROR (demangle_expression (dm));
 
3247
      RETURN_IF_ERROR (result_add_char (dm, ')'));
 
3248
 
 
3249
      /* The ternary operator takes a third operand.  */
 
3250
      if (num_args == 3)
 
3251
        {
 
3252
          RETURN_IF_ERROR (result_add (dm, ":("));
 
3253
          RETURN_IF_ERROR (demangle_expression (dm));
 
3254
          RETURN_IF_ERROR (result_add_char (dm, ')'));
 
3255
        }
 
3256
    }
 
3257
 
 
3258
  return STATUS_OK;
 
3259
}
 
3260
 
 
3261
/* Demangles and emits a <scope-expression>.  
 
3262
 
 
3263
    <scope-expression> ::= sr <qualifying type> <source-name>
 
3264
                       ::= sr <qualifying type> <encoding>  */
 
3265
 
 
3266
static status_t
 
3267
demangle_scope_expression (dm)
 
3268
     demangling_t dm;
 
3269
{
 
3270
  RETURN_IF_ERROR (demangle_char (dm, 's'));
 
3271
  RETURN_IF_ERROR (demangle_char (dm, 'r'));
 
3272
  RETURN_IF_ERROR (demangle_type (dm));
 
3273
  RETURN_IF_ERROR (result_add (dm, "::"));
 
3274
  RETURN_IF_ERROR (demangle_encoding (dm));
 
3275
  return STATUS_OK;
 
3276
}
 
3277
 
 
3278
/* Demangles and emits an <expr-primary>.  
 
3279
 
 
3280
    <expr-primary> ::= <template-param>
 
3281
                   ::= L <type> <value number> E  # literal
 
3282
                   ::= L <mangled-name> E         # external name  */
 
3283
 
 
3284
static status_t
 
3285
demangle_expr_primary (dm)
 
3286
     demangling_t dm;
 
3287
{
 
3288
  char peek = peek_char (dm);
 
3289
 
 
3290
  DEMANGLE_TRACE ("expr-primary", dm);
 
3291
 
 
3292
  if (peek == 'T')
 
3293
    RETURN_IF_ERROR (demangle_template_param (dm));
 
3294
  else if (peek == 'L')
 
3295
    {
 
3296
      /* Consume the `L'.  */
 
3297
      advance_char (dm);
 
3298
      peek = peek_char (dm);
 
3299
 
 
3300
      if (peek == '_')
 
3301
        RETURN_IF_ERROR (demangle_mangled_name (dm));
 
3302
      else
 
3303
        RETURN_IF_ERROR (demangle_literal (dm));
 
3304
 
 
3305
      RETURN_IF_ERROR (demangle_char (dm, 'E'));
 
3306
    }
 
3307
  else
 
3308
    return STATUS_ERROR;
 
3309
 
 
3310
  return STATUS_OK;
 
3311
}
 
3312
 
 
3313
/* Demangles and emits a <substitution>.  Sets *TEMPLATE_P to non-zero
 
3314
   if the substitution is the name of a template, zero otherwise. 
 
3315
 
 
3316
     <substitution> ::= S <seq-id> _
 
3317
                    ::= S_
 
3318
 
 
3319
                    ::= St   # ::std::
 
3320
                    ::= Sa   # ::std::allocator
 
3321
                    ::= Sb   # ::std::basic_string
 
3322
                    ::= Ss   # ::std::basic_string<char,
 
3323
                                                   ::std::char_traits<char>,
 
3324
                                                   ::std::allocator<char> >
 
3325
                    ::= Si   # ::std::basic_istream<char,  
 
3326
                                                    std::char_traits<char> >
 
3327
                    ::= So   # ::std::basic_ostream<char,  
 
3328
                                                    std::char_traits<char> >
 
3329
                    ::= Sd   # ::std::basic_iostream<char, 
 
3330
                                                    std::char_traits<char> >
 
3331
*/
 
3332
 
 
3333
static status_t
 
3334
demangle_substitution (dm, template_p)
 
3335
     demangling_t dm;
 
3336
     int *template_p;
 
3337
{
 
3338
  int seq_id;
 
3339
  int peek;
 
3340
  dyn_string_t text;
 
3341
 
 
3342
  DEMANGLE_TRACE ("substitution", dm);
 
3343
 
 
3344
  RETURN_IF_ERROR (demangle_char (dm, 'S'));
 
3345
 
 
3346
  /* Scan the substitution sequence index.  A missing number denotes
 
3347
     the first index.  */
 
3348
  peek = peek_char (dm);
 
3349
  if (peek == '_')
 
3350
    seq_id = -1;
 
3351
  /* If the following character is 0-9 or a capital letter, interpret
 
3352
     the sequence up to the next underscore as a base-36 substitution
 
3353
     index.  */
 
3354
  else if (IS_DIGIT ((unsigned char) peek) 
 
3355
           || (peek >= 'A' && peek <= 'Z'))
 
3356
    RETURN_IF_ERROR (demangle_number (dm, &seq_id, 36, 0));
 
3357
  else 
 
3358
    {
 
3359
      const char *new_last_source_name = NULL;
 
3360
 
 
3361
      switch (peek)
 
3362
        {
 
3363
        case 't':
 
3364
          RETURN_IF_ERROR (result_add (dm, "std"));
 
3365
          break;
 
3366
 
 
3367
        case 'a':
 
3368
          RETURN_IF_ERROR (result_add (dm, "std::allocator"));
 
3369
          new_last_source_name = "allocator";
 
3370
          *template_p = 1;
 
3371
          break;
 
3372
 
 
3373
        case 'b':
 
3374
          RETURN_IF_ERROR (result_add (dm, "std::basic_string"));
 
3375
          new_last_source_name = "basic_string";
 
3376
          *template_p = 1;
 
3377
          break;
 
3378
          
 
3379
        case 's':
 
3380
          if (!flag_verbose)
 
3381
            {
 
3382
              RETURN_IF_ERROR (result_add (dm, "std::string"));
 
3383
              new_last_source_name = "string";
 
3384
            }
 
3385
          else
 
3386
            {
 
3387
              RETURN_IF_ERROR (result_add (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
 
3388
              new_last_source_name = "basic_string";
 
3389
            }
 
3390
          *template_p = 0;
 
3391
          break;
 
3392
 
 
3393
        case 'i':
 
3394
          if (!flag_verbose)
 
3395
            {
 
3396
              RETURN_IF_ERROR (result_add (dm, "std::istream"));
 
3397
              new_last_source_name = "istream";
 
3398
            }
 
3399
          else
 
3400
            {
 
3401
              RETURN_IF_ERROR (result_add (dm, "std::basic_istream<char, std::char_traints<char> >"));
 
3402
              new_last_source_name = "basic_istream";
 
3403
            }
 
3404
          *template_p = 0;
 
3405
          break;
 
3406
 
 
3407
        case 'o':
 
3408
          if (!flag_verbose)
 
3409
            {
 
3410
              RETURN_IF_ERROR (result_add (dm, "std::ostream"));
 
3411
              new_last_source_name = "ostream";
 
3412
            }
 
3413
          else
 
3414
            {
 
3415
              RETURN_IF_ERROR (result_add (dm, "std::basic_ostream<char, std::char_traits<char> >"));
 
3416
              new_last_source_name = "basic_ostream";
 
3417
            }
 
3418
          *template_p = 0;
 
3419
          break;
 
3420
 
 
3421
        case 'd':
 
3422
          if (!flag_verbose) 
 
3423
            {
 
3424
              RETURN_IF_ERROR (result_add (dm, "std::iostream"));
 
3425
              new_last_source_name = "iostream";
 
3426
            }
 
3427
          else
 
3428
            {
 
3429
              RETURN_IF_ERROR (result_add (dm, "std::basic_iostream<char, std::char_traits<char> >"));
 
3430
              new_last_source_name = "basic_iostream";
 
3431
            }
 
3432
          *template_p = 0;
 
3433
          break;
 
3434
 
 
3435
        default:
 
3436
          return "Unrecognized <substitution>.";
 
3437
        }
 
3438
      
 
3439
      /* Consume the character we just processed.  */
 
3440
      advance_char (dm);
 
3441
 
 
3442
      if (new_last_source_name != NULL)
 
3443
        {
 
3444
          if (!dyn_string_copy_cstr (dm->last_source_name, 
 
3445
                                     new_last_source_name))
 
3446
            return STATUS_ALLOCATION_FAILED;
 
3447
        }
 
3448
 
 
3449
      return STATUS_OK;
 
3450
    }
 
3451
 
 
3452
  /* Look up the substitution text.  Since `S_' is the most recent
 
3453
     substitution, `S0_' is the second-most-recent, etc., shift the
 
3454
     numbering by one.  */
 
3455
  text = substitution_get (dm, seq_id + 1, template_p);
 
3456
  if (text == NULL) 
 
3457
    return "Substitution number out of range.";
 
3458
 
 
3459
  /* Emit the substitution text.  */
 
3460
  RETURN_IF_ERROR (result_add_string (dm, text));
 
3461
 
 
3462
  RETURN_IF_ERROR (demangle_char (dm, '_'));
 
3463
  return STATUS_OK;
 
3464
}
 
3465
 
 
3466
/* Demangles and emits a <local-name>.  
 
3467
 
 
3468
    <local-name> := Z <function encoding> E <entity name> [<discriminator>]
 
3469
                 := Z <function encoding> E s [<discriminator>]  */
 
3470
 
 
3471
static status_t
 
3472
demangle_local_name (dm)
 
3473
     demangling_t dm;
 
3474
{
 
3475
  DEMANGLE_TRACE ("local-name", dm);
 
3476
 
 
3477
  RETURN_IF_ERROR (demangle_char (dm, 'Z'));
 
3478
  RETURN_IF_ERROR (demangle_encoding (dm));
 
3479
  RETURN_IF_ERROR (demangle_char (dm, 'E'));
 
3480
  RETURN_IF_ERROR (result_add (dm, "::"));
 
3481
 
 
3482
  if (peek_char (dm) == 's')
 
3483
    {
 
3484
      /* Local character string literal.  */
 
3485
      RETURN_IF_ERROR (result_add (dm, "string literal"));
 
3486
      /* Consume the s.  */
 
3487
      advance_char (dm);
 
3488
      RETURN_IF_ERROR (demangle_discriminator (dm, 0));
 
3489
    }
 
3490
  else
 
3491
    {
 
3492
      int unused;
 
3493
      /* Local name for some other entity.  Demangle its name.  */
 
3494
      RETURN_IF_ERROR (demangle_name (dm, &unused));
 
3495
      RETURN_IF_ERROR (demangle_discriminator (dm, 1));
 
3496
     }
 
3497
 
 
3498
   return STATUS_OK;
 
3499
 }
 
3500
 
 
3501
 /* Optimonally demangles and emits a <discriminator>.  If there is no
 
3502
    <discriminator> at the current position in the mangled string, the
 
3503
    descriminator is assumed to be zero.  Emit the discriminator number
 
3504
    in parentheses, unless SUPPRESS_FIRST is non-zero and the
 
3505
    discriminator is zero.  
 
3506
 
 
3507
     <discriminator> ::= _ <number>  */
 
3508
 
 
3509
static status_t
 
3510
demangle_discriminator (dm, suppress_first)
 
3511
     demangling_t dm;
 
3512
     int suppress_first;
 
3513
{
 
3514
  /* Output for <discriminator>s to the demangled name is completely
 
3515
     suppressed if not in verbose mode.  */
 
3516
 
 
3517
  if (peek_char (dm) == '_')
 
3518
    {
 
3519
      /* Consume the underscore.  */
 
3520
      advance_char (dm);
 
3521
      if (flag_verbose)
 
3522
        RETURN_IF_ERROR (result_add (dm, " [#"));
 
3523
      /* Check if there's a number following the underscore.  */
 
3524
      if (IS_DIGIT ((unsigned char) peek_char (dm)))
 
3525
        {
 
3526
          int discriminator;
 
3527
          /* Demangle the number.  */
 
3528
          RETURN_IF_ERROR (demangle_number (dm, &discriminator, 10, 0));
 
3529
          if (flag_verbose)
 
3530
            /* Write the discriminator.  The mangled number is two
 
3531
               less than the discriminator ordinal, counting from
 
3532
               zero.  */
 
3533
            RETURN_IF_ERROR (int_to_dyn_string (discriminator + 1,
 
3534
                                                (dyn_string_t) dm->result));
 
3535
        }
 
3536
      else
 
3537
        return STATUS_ERROR;
 
3538
      if (flag_verbose)
 
3539
        RETURN_IF_ERROR (result_add_char (dm, ']'));
 
3540
    }
 
3541
  else if (!suppress_first)
 
3542
    {
 
3543
      if (flag_verbose)
 
3544
        RETURN_IF_ERROR (result_add (dm, " [#0]"));
 
3545
    }
 
3546
 
 
3547
  return STATUS_OK;
 
3548
}
 
3549
 
 
3550
/* Demangle NAME into RESULT, which must be an initialized
 
3551
   dyn_string_t.  On success, returns STATUS_OK.  On failure, returns
 
3552
   an error message, and the contents of RESULT are unchanged.  */
 
3553
 
 
3554
static status_t
 
3555
cp_demangle (name, result, style)
 
3556
     const char *name;
 
3557
     dyn_string_t result;
 
3558
     int style;
 
3559
{
 
3560
  status_t status;
 
3561
  int length = strlen (name);
 
3562
 
 
3563
  if (length > 2 && name[0] == '_' && name[1] == 'Z')
 
3564
    {
 
3565
      demangling_t dm = demangling_new (name, style);
 
3566
      if (dm == NULL)
 
3567
        return STATUS_ALLOCATION_FAILED;
 
3568
 
 
3569
      status = result_push (dm);
 
3570
      if (status != STATUS_OK)
 
3571
        {
 
3572
          demangling_delete (dm);
 
3573
          return status;
 
3574
        }
 
3575
 
 
3576
      status = demangle_mangled_name (dm);
 
3577
      if (STATUS_NO_ERROR (status))
 
3578
        {
 
3579
          dyn_string_t demangled = (dyn_string_t) result_pop (dm);
 
3580
          if (!dyn_string_copy (result, demangled))
 
3581
            return STATUS_ALLOCATION_FAILED;
 
3582
          dyn_string_delete (demangled);
 
3583
        }
 
3584
      
 
3585
      demangling_delete (dm);
 
3586
    }
 
3587
  else
 
3588
    {
 
3589
      /* It's evidently not a mangled C++ name.  It could be the name
 
3590
         of something with C linkage, though, so just copy NAME into
 
3591
         RESULT.  */
 
3592
      if (!dyn_string_copy_cstr (result, name))
 
3593
        return STATUS_ALLOCATION_FAILED;
 
3594
      status = STATUS_OK;
 
3595
    }
 
3596
 
 
3597
  return status; 
 
3598
}
 
3599
 
 
3600
/* Demangle TYPE_NAME into RESULT, which must be an initialized
 
3601
   dyn_string_t.  On success, returns STATUS_OK.  On failiure, returns
 
3602
   an error message, and the contents of RESULT are unchanged.  */
 
3603
 
 
3604
static status_t
 
3605
cp_demangle_type (type_name, result)
 
3606
     const char* type_name;
 
3607
     dyn_string_t result;
 
3608
{
 
3609
  status_t status;
 
3610
  demangling_t dm = demangling_new (type_name, DMGL_GNU_V3);
 
3611
  
 
3612
  if (dm == NULL)
 
3613
    return STATUS_ALLOCATION_FAILED;
 
3614
 
 
3615
  /* Demangle the type name.  The demangled name is stored in dm.  */
 
3616
  status = result_push (dm);
 
3617
  if (status != STATUS_OK)
 
3618
    {
 
3619
      demangling_delete (dm);
 
3620
      return status;
 
3621
    }
 
3622
 
 
3623
  status = demangle_type (dm);
 
3624
 
 
3625
  if (STATUS_NO_ERROR (status))
 
3626
    {
 
3627
      /* The demangling succeeded.  Pop the result out of dm and copy
 
3628
         it into RESULT.  */
 
3629
      dyn_string_t demangled = (dyn_string_t) result_pop (dm);
 
3630
      if (!dyn_string_copy (result, demangled))
 
3631
        return STATUS_ALLOCATION_FAILED;
 
3632
      dyn_string_delete (demangled);
 
3633
    }
 
3634
 
 
3635
  /* Clean up.  */
 
3636
  demangling_delete (dm);
 
3637
 
 
3638
  return status;
 
3639
}
 
3640
 
 
3641
#if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3)
 
3642
extern char *__cxa_demangle PARAMS ((const char *, char *, size_t *, int *));
 
3643
 
 
3644
/* ia64 ABI-mandated entry point in the C++ runtime library for performing
 
3645
   demangling.  MANGLED_NAME is a NUL-terminated character string
 
3646
   containing the name to be demangled.  
 
3647
 
 
3648
   OUTPUT_BUFFER is a region of memory, allocated with malloc, of
 
3649
   *LENGTH bytes, into which the demangled name is stored.  If
 
3650
   OUTPUT_BUFFER is not long enough, it is expanded using realloc.
 
3651
   OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
 
3652
   is placed in a region of memory allocated with malloc.  
 
3653
 
 
3654
   If LENGTH is non-NULL, the length of the buffer conaining the
 
3655
   demangled name, is placed in *LENGTH.  
 
3656
 
 
3657
   The return value is a pointer to the start of the NUL-terminated
 
3658
   demangled name, or NULL if the demangling fails.  The caller is
 
3659
   responsible for deallocating this memory using free.  
 
3660
 
 
3661
   *STATUS is set to one of the following values:
 
3662
      0: The demangling operation succeeded.
 
3663
     -1: A memory allocation failiure occurred.
 
3664
     -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
 
3665
     -3: One of the arguments is invalid.
 
3666
 
 
3667
   The demagling is performed using the C++ ABI mangling rules, with
 
3668
   GNU extensions.  */
 
3669
 
 
3670
char *
 
3671
__cxa_demangle (mangled_name, output_buffer, length, status)
 
3672
     const char *mangled_name;
 
3673
     char *output_buffer;
 
3674
     size_t *length;
 
3675
     int *status;
 
3676
{
 
3677
  struct dyn_string demangled_name;
 
3678
  status_t result;
 
3679
 
 
3680
  if (status == NULL)
 
3681
    return NULL;
 
3682
 
 
3683
  if (mangled_name == NULL) {
 
3684
    *status = -3;
 
3685
    return NULL;
 
3686
  }
 
3687
 
 
3688
  /* Did the caller provide a buffer for the demangled name?  */
 
3689
  if (output_buffer == NULL) {
 
3690
    /* No; dyn_string will malloc a buffer for us.  */
 
3691
    if (!dyn_string_init (&demangled_name, 0)) 
 
3692
      {
 
3693
        *status = -1;
 
3694
        return NULL;
 
3695
      }
 
3696
  }
 
3697
  else {
 
3698
    /* Yes.  Check that the length was provided.  */
 
3699
    if (length == NULL) {
 
3700
      *status = -3;
 
3701
      return NULL;
 
3702
    }
 
3703
    /* Install the buffer into a dyn_string.  */
 
3704
    demangled_name.allocated = *length;
 
3705
    demangled_name.length = 0;
 
3706
    demangled_name.s = output_buffer;
 
3707
  }
 
3708
 
 
3709
  if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
 
3710
    /* MANGLED_NAME apprears to be a function or variable name.
 
3711
       Demangle it accordingly.  */
 
3712
    result = cp_demangle (mangled_name, &demangled_name, 0);
 
3713
  else
 
3714
    /* Try to demangled MANGLED_NAME as the name of a type.  */
 
3715
    result = cp_demangle_type (mangled_name, &demangled_name);
 
3716
 
 
3717
  if (result == STATUS_OK) 
 
3718
    /* The demangling succeeded.  */
 
3719
    {
 
3720
      /* If LENGTH isn't NULL, store the allocated buffer length
 
3721
         there; the buffer may have been realloced by dyn_string
 
3722
         functions.  */
 
3723
      if (length != NULL)
 
3724
        *length = demangled_name.allocated;
 
3725
      /* The operation was a success.  */
 
3726
      *status = 0;
 
3727
      return dyn_string_buf (&demangled_name);
 
3728
    }
 
3729
  else if (result == STATUS_ALLOCATION_FAILED)
 
3730
    /* A call to malloc or realloc failed during the demangling
 
3731
       operation.  */
 
3732
    {
 
3733
      *status = -1;
 
3734
      return NULL;
 
3735
    }
 
3736
  else
 
3737
    /* The demangling failed for another reason, most probably because
 
3738
       MANGLED_NAME isn't a valid mangled name.  */
 
3739
    {
 
3740
      /* If the buffer containing the demangled name wasn't provided
 
3741
         by the caller, free it.  */
 
3742
      if (output_buffer == NULL)
 
3743
        free (dyn_string_buf (&demangled_name));
 
3744
      *status = -2;
 
3745
      return NULL;
 
3746
    }
 
3747
}
 
3748
 
 
3749
#else /* ! (IN_LIBGCC2 || IN_GLIBCPP_V3) */
 
3750
 
 
3751
/* Variant entry point for integration with the existing cplus-dem
 
3752
   demangler.  Attempts to demangle MANGLED.  If the demangling
 
3753
   succeeds, returns a buffer, allocated with malloc, containing the
 
3754
   demangled name.  The caller must deallocate the buffer using free.
 
3755
   If the demangling failes, returns NULL.  */
 
3756
 
 
3757
char *
 
3758
cplus_demangle_v3 (mangled, options)
 
3759
     const char* mangled;
 
3760
     int options;
 
3761
{
 
3762
  dyn_string_t demangled;
 
3763
  status_t status;
 
3764
  int type = !!(options & DMGL_TYPES);
 
3765
 
 
3766
  if (mangled[0] == '_' && mangled[1] == 'Z')
 
3767
    /* It is not a type.  */
 
3768
    type = 0;
 
3769
  else
 
3770
    {
 
3771
      /* It is a type. Stop if we don't want to demangle types. */
 
3772
      if (!type)
 
3773
        return NULL;
 
3774
    }
 
3775
 
 
3776
  flag_verbose = !!(options & DMGL_VERBOSE);
 
3777
 
 
3778
  /* Create a dyn_string to hold the demangled name.  */
 
3779
  demangled = dyn_string_new (0);
 
3780
  /* Attempt the demangling.  */
 
3781
  if (!type)
 
3782
    /* Appears to be a function or variable name.  */
 
3783
    status = cp_demangle (mangled, demangled, 0);
 
3784
  else
 
3785
    /* Try to demangle it as the name of a type.  */
 
3786
    status = cp_demangle_type (mangled, demangled);
 
3787
 
 
3788
  if (STATUS_NO_ERROR (status))
 
3789
    /* Demangling succeeded.  */
 
3790
    {
 
3791
      /* Grab the demangled result from the dyn_string.  It was
 
3792
         allocated with malloc, so we can return it directly.  */
 
3793
      char *return_value = dyn_string_release (demangled);
 
3794
      /* Hand back the demangled name.  */
 
3795
      return return_value;
 
3796
    }
 
3797
  else if (status == STATUS_ALLOCATION_FAILED)
 
3798
    {
 
3799
      fprintf (stderr, "Memory allocation failed.\n");
 
3800
      abort ();
 
3801
    }
 
3802
  else
 
3803
    /* Demangling failed.  */
 
3804
    {
 
3805
      dyn_string_delete (demangled);
 
3806
      return NULL;
 
3807
    }
 
3808
}
 
3809
 
 
3810
/* Demangle a Java symbol.  Java uses a subset of the V3 ABI C++ mangling 
 
3811
   conventions, but the output formatting is a little different.
 
3812
   This instructs the C++ demangler not to emit pointer characters ("*"), and 
 
3813
   to use Java's namespace separator symbol ("." instead of "::").  It then 
 
3814
   does an additional pass over the demangled output to replace instances 
 
3815
   of JArray<TYPE> with TYPE[].  */
 
3816
 
 
3817
char *
 
3818
java_demangle_v3 (mangled)
 
3819
     const char* mangled;
 
3820
{
 
3821
  dyn_string_t demangled;
 
3822
  char *next;
 
3823
  char *end;
 
3824
  int len;
 
3825
  status_t status;
 
3826
  int nesting = 0;
 
3827
  char *cplus_demangled;
 
3828
  char *return_value;
 
3829
    
 
3830
  /* Create a dyn_string to hold the demangled name.  */
 
3831
  demangled = dyn_string_new (0);
 
3832
 
 
3833
  /* Attempt the demangling.  */
 
3834
  status = cp_demangle ((char *) mangled, demangled, DMGL_JAVA);
 
3835
 
 
3836
  if (STATUS_NO_ERROR (status))
 
3837
    /* Demangling succeeded.  */
 
3838
    {
 
3839
      /* Grab the demangled result from the dyn_string. */
 
3840
      cplus_demangled = dyn_string_release (demangled);
 
3841
    }
 
3842
  else if (status == STATUS_ALLOCATION_FAILED)
 
3843
    {
 
3844
      fprintf (stderr, "Memory allocation failed.\n");
 
3845
      abort ();
 
3846
    }
 
3847
  else
 
3848
    /* Demangling failed.  */
 
3849
    {
 
3850
      dyn_string_delete (demangled);
 
3851
      return NULL;
 
3852
    }
 
3853
  
 
3854
  len = strlen (cplus_demangled);
 
3855
  next = cplus_demangled;
 
3856
  end = next + len;
 
3857
  demangled = NULL;
 
3858
 
 
3859
  /* Replace occurances of JArray<TYPE> with TYPE[]. */
 
3860
  while (next < end)
 
3861
    {
 
3862
      char *open_str = strstr (next, "JArray<");
 
3863
      char *close_str = NULL;
 
3864
      if (nesting > 0)
 
3865
        close_str = strchr (next, '>');
 
3866
    
 
3867
      if (open_str != NULL && (close_str == NULL || close_str > open_str))
 
3868
        {
 
3869
          ++nesting;
 
3870
          
 
3871
          if (!demangled)
 
3872
            demangled = dyn_string_new(len);
 
3873
 
 
3874
          /* Copy prepending symbols, if any. */
 
3875
          if (open_str > next)
 
3876
            {
 
3877
              open_str[0] = 0;
 
3878
              dyn_string_append_cstr (demangled, next);
 
3879
            }     
 
3880
          next = open_str + 7;
 
3881
        }
 
3882
      else if (close_str != NULL)
 
3883
        {
 
3884
          --nesting;
 
3885
          
 
3886
          /* Copy prepending type symbol, if any. Squash any spurious 
 
3887
             whitespace. */
 
3888
          if (close_str > next && next[0] != ' ')
 
3889
            {
 
3890
              close_str[0] = 0;
 
3891
              dyn_string_append_cstr (demangled, next);
 
3892
            }
 
3893
          dyn_string_append_cstr (demangled, "[]");       
 
3894
          next = close_str + 1;
 
3895
        }
 
3896
      else
 
3897
        {
 
3898
          /* There are no more arrays. Copy the rest of the symbol, or
 
3899
             simply return the original symbol if no changes were made. */
 
3900
          if (next == cplus_demangled)
 
3901
            return cplus_demangled;
 
3902
 
 
3903
          dyn_string_append_cstr (demangled, next);
 
3904
          next = end;
 
3905
        }
 
3906
    }
 
3907
 
 
3908
  free (cplus_demangled);
 
3909
  
 
3910
  if (demangled)
 
3911
    return_value = dyn_string_release (demangled);
 
3912
  else
 
3913
    return_value = NULL;
 
3914
 
 
3915
  return return_value;
 
3916
}
 
3917
 
 
3918
#endif /* IN_LIBGCC2 || IN_GLIBCPP_V3 */
 
3919
 
 
3920
 
 
3921
#ifndef IN_GLIBCPP_V3
 
3922
/* Demangle NAME in the G++ V3 ABI demangling style, and return either
 
3923
   zero, indicating that some error occurred, or a demangling_t
 
3924
   holding the results.  */
 
3925
static demangling_t
 
3926
demangle_v3_with_details (name)
 
3927
     const char *name;
 
3928
{
 
3929
  demangling_t dm;
 
3930
  status_t status;
 
3931
 
 
3932
  if (strncmp (name, "_Z", 2))
 
3933
    return 0;
 
3934
 
 
3935
  dm = demangling_new (name, DMGL_GNU_V3);
 
3936
  if (dm == NULL)
 
3937
    {
 
3938
      fprintf (stderr, "Memory allocation failed.\n");
 
3939
      abort ();
 
3940
    }
 
3941
 
 
3942
  status = result_push (dm);
 
3943
  if (! STATUS_NO_ERROR (status))
 
3944
    {
 
3945
      demangling_delete (dm);
 
3946
      fprintf (stderr, "%s\n", status);
 
3947
      abort ();
 
3948
    }
 
3949
 
 
3950
  status = demangle_mangled_name (dm);
 
3951
  if (STATUS_NO_ERROR (status))
 
3952
    return dm;
 
3953
 
 
3954
  demangling_delete (dm);
 
3955
  return 0;
 
3956
}
 
3957
 
 
3958
 
 
3959
/* Return non-zero iff NAME is the mangled form of a constructor name
 
3960
   in the G++ V3 ABI demangling style.  Specifically, return:
 
3961
   - '1' if NAME is a complete object constructor,
 
3962
   - '2' if NAME is a base object constructor, or
 
3963
   - '3' if NAME is a complete object allocating constructor.  */
 
3964
enum gnu_v3_ctor_kinds
 
3965
is_gnu_v3_mangled_ctor (name)
 
3966
     const char *name;
 
3967
{
 
3968
  demangling_t dm = demangle_v3_with_details (name);
 
3969
 
 
3970
  if (dm)
 
3971
    {
 
3972
      enum gnu_v3_ctor_kinds result = dm->is_constructor;
 
3973
      demangling_delete (dm);
 
3974
      return result;
 
3975
    }
 
3976
  else
 
3977
    return 0;
 
3978
}
 
3979
 
 
3980
 
 
3981
/* Return non-zero iff NAME is the mangled form of a destructor name
 
3982
   in the G++ V3 ABI demangling style.  Specifically, return:
 
3983
   - '0' if NAME is a deleting destructor,
 
3984
   - '1' if NAME is a complete object destructor, or
 
3985
   - '2' if NAME is a base object destructor.  */
 
3986
enum gnu_v3_dtor_kinds
 
3987
is_gnu_v3_mangled_dtor (name)
 
3988
     const char *name;
 
3989
{
 
3990
  demangling_t dm = demangle_v3_with_details (name);
 
3991
 
 
3992
  if (dm)
 
3993
    {
 
3994
      enum gnu_v3_dtor_kinds result = dm->is_destructor;
 
3995
      demangling_delete (dm);
 
3996
      return result;
 
3997
    }
 
3998
  else
 
3999
    return 0;
 
4000
}
 
4001
#endif /* IN_GLIBCPP_V3 */
 
4002
 
 
4003
 
 
4004
#ifdef STANDALONE_DEMANGLER
 
4005
 
 
4006
#include "getopt.h"
 
4007
 
 
4008
static void print_usage
 
4009
  PARAMS ((FILE* fp, int exit_value));
 
4010
 
 
4011
/* Non-zero if CHAR is a character than can occur in a mangled name.  */
 
4012
#define is_mangled_char(CHAR)                                           \
 
4013
  (IS_ALPHA (CHAR) || IS_DIGIT (CHAR)                                   \
 
4014
   || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
 
4015
 
 
4016
/* The name of this program, as invoked.  */
 
4017
const char* program_name;
 
4018
 
 
4019
/* Prints usage summary to FP and then exits with EXIT_VALUE.  */
 
4020
 
 
4021
static void
 
4022
print_usage (fp, exit_value)
 
4023
     FILE* fp;
 
4024
     int exit_value;
 
4025
{
 
4026
  fprintf (fp, "Usage: %s [options] [names ...]\n", program_name);
 
4027
  fprintf (fp, "Options:\n");
 
4028
  fprintf (fp, "  -h,--help       Display this message.\n");
 
4029
  fprintf (fp, "  -s,--strict     Demangle standard names only.\n");
 
4030
  fprintf (fp, "  -v,--verbose    Produce verbose demanglings.\n");
 
4031
  fprintf (fp, "If names are provided, they are demangled.  Otherwise filters standard input.\n");
 
4032
 
 
4033
  exit (exit_value);
 
4034
}
 
4035
 
 
4036
/* Option specification for getopt_long.  */
 
4037
static const struct option long_options[] = 
 
4038
{
 
4039
  { "help",    no_argument, NULL, 'h' },
 
4040
  { "strict",  no_argument, NULL, 's' },
 
4041
  { "verbose", no_argument, NULL, 'v' },
 
4042
  { NULL,      no_argument, NULL, 0   },
 
4043
};
 
4044
 
 
4045
/* Main entry for a demangling filter executable.  It will demangle
 
4046
   its command line arguments, if any.  If none are provided, it will
 
4047
   filter stdin to stdout, replacing any recognized mangled C++ names
 
4048
   with their demangled equivalents.  */
 
4049
 
 
4050
int
 
4051
main (argc, argv)
 
4052
     int argc;
 
4053
     char *argv[];
 
4054
{
 
4055
  status_t status;
 
4056
  int i;
 
4057
  int opt_char;
 
4058
 
 
4059
  /* Use the program name of this program, as invoked.  */
 
4060
  program_name = argv[0];
 
4061
 
 
4062
  /* Parse options.  */
 
4063
  do 
 
4064
    {
 
4065
      opt_char = getopt_long (argc, argv, "hsv", long_options, NULL);
 
4066
      switch (opt_char)
 
4067
        {
 
4068
        case '?':  /* Unrecognized option.  */
 
4069
          print_usage (stderr, 1);
 
4070
          break;
 
4071
 
 
4072
        case 'h':
 
4073
          print_usage (stdout, 0);
 
4074
          break;
 
4075
 
 
4076
        case 's':
 
4077
          flag_strict = 1;
 
4078
          break;
 
4079
 
 
4080
        case 'v':
 
4081
          flag_verbose = 1;
 
4082
          break;
 
4083
        }
 
4084
    }
 
4085
  while (opt_char != -1);
 
4086
 
 
4087
  if (optind == argc) 
 
4088
    /* No command line arguments were provided.  Filter stdin.  */
 
4089
    {
 
4090
      dyn_string_t mangled = dyn_string_new (3);
 
4091
      dyn_string_t demangled = dyn_string_new (0);
 
4092
      status_t status;
 
4093
 
 
4094
      /* Read all of input.  */
 
4095
      while (!feof (stdin))
 
4096
        {
 
4097
          char c = getchar ();
 
4098
 
 
4099
          /* The first character of a mangled name is an underscore.  */
 
4100
          if (feof (stdin))
 
4101
            break;
 
4102
          if (c != '_')
 
4103
            {
 
4104
              /* It's not a mangled name.  Print the character and go
 
4105
                 on.  */
 
4106
              putchar (c);
 
4107
              continue;
 
4108
            }
 
4109
          c = getchar ();
 
4110
          
 
4111
          /* The second character of a mangled name is a capital `Z'.  */
 
4112
          if (feof (stdin))
 
4113
            break;
 
4114
          if (c != 'Z')
 
4115
            {
 
4116
              /* It's not a mangled name.  Print the previous
 
4117
                 underscore, the `Z', and go on.  */
 
4118
              putchar ('_');
 
4119
              putchar (c);
 
4120
              continue;
 
4121
            }
 
4122
 
 
4123
          /* Start keeping track of the candidate mangled name.  */
 
4124
          dyn_string_append_char (mangled, '_');
 
4125
          dyn_string_append_char (mangled, 'Z');
 
4126
 
 
4127
          /* Pile characters into mangled until we hit one that can't
 
4128
             occur in a mangled name.  */
 
4129
          c = getchar ();
 
4130
          while (!feof (stdin) && is_mangled_char (c))
 
4131
            {
 
4132
              dyn_string_append_char (mangled, c);
 
4133
              if (feof (stdin))
 
4134
                break;
 
4135
              c = getchar ();
 
4136
            }
 
4137
 
 
4138
          /* Attempt to demangle the name.  */
 
4139
          status = cp_demangle (dyn_string_buf (mangled), demangled, 0);
 
4140
 
 
4141
          /* If the demangling succeeded, great!  Print out the
 
4142
             demangled version.  */
 
4143
          if (STATUS_NO_ERROR (status))
 
4144
            fputs (dyn_string_buf (demangled), stdout);
 
4145
          /* Abort on allocation failures.  */
 
4146
          else if (status == STATUS_ALLOCATION_FAILED)
 
4147
            {
 
4148
              fprintf (stderr, "Memory allocation failed.\n");
 
4149
              abort ();
 
4150
            }
 
4151
          /* Otherwise, it might not have been a mangled name.  Just
 
4152
             print out the original text.  */
 
4153
          else
 
4154
            fputs (dyn_string_buf (mangled), stdout);
 
4155
 
 
4156
          /* If we haven't hit EOF yet, we've read one character that
 
4157
             can't occur in a mangled name, so print it out.  */
 
4158
          if (!feof (stdin))
 
4159
            putchar (c);
 
4160
 
 
4161
          /* Clear the candidate mangled name, to start afresh next
 
4162
             time we hit a `_Z'.  */
 
4163
          dyn_string_clear (mangled);
 
4164
        }
 
4165
 
 
4166
      dyn_string_delete (mangled);
 
4167
      dyn_string_delete (demangled);
 
4168
    }
 
4169
  else
 
4170
    /* Demangle command line arguments.  */
 
4171
    {
 
4172
      dyn_string_t result = dyn_string_new (0);
 
4173
 
 
4174
      /* Loop over command line arguments.  */
 
4175
      for (i = optind; i < argc; ++i)
 
4176
        {
 
4177
          /* Attempt to demangle.  */
 
4178
          status = cp_demangle (argv[i], result, 0);
 
4179
 
 
4180
          /* If it worked, print the demangled name.  */
 
4181
          if (STATUS_NO_ERROR (status))
 
4182
            printf ("%s\n", dyn_string_buf (result));
 
4183
          /* Abort on allocaiton failures.  */
 
4184
          else if (status == STATUS_ALLOCATION_FAILED)
 
4185
            {
 
4186
              fprintf (stderr, "Memory allocation failed.\n");
 
4187
              abort ();
 
4188
            }
 
4189
          /* If not, print the error message to stderr instead.  */
 
4190
          else 
 
4191
            fprintf (stderr, "%s\n", status);
 
4192
        }
 
4193
      dyn_string_delete (result);
 
4194
    }
 
4195
 
 
4196
  return 0;
 
4197
}
 
4198
 
 
4199
#endif /* STANDALONE_DEMANGLER */