OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [cp-name-parser.y] - Blame information for rev 842

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* YACC parser for C++ names, for GDB.
2
 
3
   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
 
6
   Parts of the lexer are based on c-exp.y from GDB.
7
 
8
   This file is part of GDB.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program.  If not, see .  */
22
 
23
/* Note that malloc's and realloc's in this file are transformed to
24
   xmalloc and xrealloc respectively by the same sed command in the
25
   makefile that remaps any other malloc/realloc inserted by the parser
26
   generator.  Doing this with #defines and trying to control the interaction
27
   with include files ( and  for example) just became
28
   too messy, particularly when such includes can be inserted at random
29
   times by the parser generator.  */
30
 
31
%{
32
 
33
#include "defs.h"
34
 
35
#include 
36
#include 
37
#include 
38
#include 
39
 
40
#include "safe-ctype.h"
41
#include "libiberty.h"
42
#include "demangle.h"
43
#include "cp-support.h"
44
 
45
/* Bison does not make it easy to create a parser without global
46
   state, unfortunately.  Here are all the global variables used
47
   in this parser.  */
48
 
49
/* LEXPTR is the current pointer into our lex buffer.  PREV_LEXPTR
50
   is the start of the last token lexed, only used for diagnostics.
51
   ERROR_LEXPTR is the first place an error occurred.  GLOBAL_ERRMSG
52
   is the first error message encountered.  */
53
 
54
static const char *lexptr, *prev_lexptr, *error_lexptr, *global_errmsg;
55
 
56
/* The components built by the parser are allocated ahead of time,
57
   and cached in this structure.  */
58
 
59
#define ALLOC_CHUNK 100
60
 
61
struct demangle_info {
62
  int used;
63
  struct demangle_info *prev, *next;
64
  struct demangle_component comps[ALLOC_CHUNK];
65
};
66
 
67
static struct demangle_info *demangle_info;
68
 
69
static struct demangle_component *
70
d_grab (void)
71
{
72
  struct demangle_info *more;
73
 
74
  if (demangle_info->used >= ALLOC_CHUNK)
75
    {
76
      if (demangle_info->next == NULL)
77
        {
78
          more = malloc (sizeof (struct demangle_info));
79
          more->prev = demangle_info;
80
          more->next = NULL;
81
          demangle_info->next = more;
82
        }
83
      else
84
        more = demangle_info->next;
85
 
86
      more->used = 0;
87
      demangle_info = more;
88
    }
89
  return &demangle_info->comps[demangle_info->used++];
90
}
91
 
92
/* The parse tree created by the parser is stored here after a successful
93
   parse.  */
94
 
95
static struct demangle_component *global_result;
96
 
97
/* Prototypes for helper functions used when constructing the parse
98
   tree.  */
99
 
100
static struct demangle_component *d_qualify (struct demangle_component *, int,
101
                                             int);
102
 
103
static struct demangle_component *d_int_type (int);
104
 
105
static struct demangle_component *d_unary (const char *,
106
                                           struct demangle_component *);
107
static struct demangle_component *d_binary (const char *,
108
                                            struct demangle_component *,
109
                                            struct demangle_component *);
110
 
111
/* Flags passed to d_qualify.  */
112
 
113
#define QUAL_CONST 1
114
#define QUAL_RESTRICT 2
115
#define QUAL_VOLATILE 4
116
 
117
/* Flags passed to d_int_type.  */
118
 
119
#define INT_CHAR        (1 << 0)
120
#define INT_SHORT       (1 << 1)
121
#define INT_LONG        (1 << 2)
122
#define INT_LLONG       (1 << 3)
123
 
124
#define INT_SIGNED      (1 << 4)
125
#define INT_UNSIGNED    (1 << 5)
126
 
127
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
128
   as well as gratuitiously global symbol names, so we can have multiple
129
   yacc generated parsers in gdb.  Note that these are only the variables
130
   produced by yacc.  If other parser generators (bison, byacc, etc) produce
131
   additional global names that conflict at link time, then those parser
132
   generators need to be fixed instead of adding those names to this list. */
133
 
134
#define yymaxdepth cpname_maxdepth
135
#define yyparse cpname_parse
136
#define yylex   cpname_lex
137
#define yyerror cpname_error
138
#define yylval  cpname_lval
139
#define yychar  cpname_char
140
#define yydebug cpname_debug
141
#define yypact  cpname_pact
142
#define yyr1    cpname_r1
143
#define yyr2    cpname_r2
144
#define yydef   cpname_def
145
#define yychk   cpname_chk
146
#define yypgo   cpname_pgo
147
#define yyact   cpname_act
148
#define yyexca  cpname_exca
149
#define yyerrflag cpname_errflag
150
#define yynerrs cpname_nerrs
151
#define yyps    cpname_ps
152
#define yypv    cpname_pv
153
#define yys     cpname_s
154
#define yy_yys  cpname_yys
155
#define yystate cpname_state
156
#define yytmp   cpname_tmp
157
#define yyv     cpname_v
158
#define yy_yyv  cpname_yyv
159
#define yyval   cpname_val
160
#define yylloc  cpname_lloc
161
#define yyreds  cpname_reds             /* With YYDEBUG defined */
162
#define yytoks  cpname_toks             /* With YYDEBUG defined */
163
#define yyname  cpname_name             /* With YYDEBUG defined */
164
#define yyrule  cpname_rule             /* With YYDEBUG defined */
165
#define yylhs   cpname_yylhs
166
#define yylen   cpname_yylen
167
#define yydefred cpname_yydefred
168
#define yydgoto cpname_yydgoto
169
#define yysindex cpname_yysindex
170
#define yyrindex cpname_yyrindex
171
#define yygindex cpname_yygindex
172
#define yytable  cpname_yytable
173
#define yycheck  cpname_yycheck
174
 
175
int yyparse (void);
176
static int yylex (void);
177
static void yyerror (char *);
178
 
179
/* Enable yydebug for the stand-alone parser.  */
180
#ifdef TEST_CPNAMES
181
# define YYDEBUG        1
182
#endif
183
 
184
/* Helper functions.  These wrap the demangler tree interface, handle
185
   allocation from our global store, and return the allocated component.  */
186
 
187
static struct demangle_component *
188
fill_comp (enum demangle_component_type d_type, struct demangle_component *lhs,
189
           struct demangle_component *rhs)
190
{
191
  struct demangle_component *ret = d_grab ();
192
  cplus_demangle_fill_component (ret, d_type, lhs, rhs);
193
  return ret;
194
}
195
 
196
static struct demangle_component *
197
make_empty (enum demangle_component_type d_type)
198
{
199
  struct demangle_component *ret = d_grab ();
200
  ret->type = d_type;
201
  return ret;
202
}
203
 
204
static struct demangle_component *
205
make_operator (const char *name, int args)
206
{
207
  struct demangle_component *ret = d_grab ();
208
  cplus_demangle_fill_operator (ret, name, args);
209
  return ret;
210
}
211
 
212
static struct demangle_component *
213
make_dtor (enum gnu_v3_dtor_kinds kind, struct demangle_component *name)
214
{
215
  struct demangle_component *ret = d_grab ();
216
  cplus_demangle_fill_dtor (ret, kind, name);
217
  return ret;
218
}
219
 
220
static struct demangle_component *
221
make_builtin_type (const char *name)
222
{
223
  struct demangle_component *ret = d_grab ();
224
  cplus_demangle_fill_builtin_type (ret, name);
225
  return ret;
226
}
227
 
228
static struct demangle_component *
229
make_name (const char *name, int len)
230
{
231
  struct demangle_component *ret = d_grab ();
232
  cplus_demangle_fill_name (ret, name, len);
233
  return ret;
234
}
235
 
236
#define d_left(dc) (dc)->u.s_binary.left
237
#define d_right(dc) (dc)->u.s_binary.right
238
 
239
%}
240
 
241
%union
242
  {
243
    struct demangle_component *comp;
244
    struct nested {
245
      struct demangle_component *comp;
246
      struct demangle_component **last;
247
    } nested;
248
    struct {
249
      struct demangle_component *comp, *last;
250
    } nested1;
251
    struct {
252
      struct demangle_component *comp, **last;
253
      struct nested fn;
254
      struct demangle_component *start;
255
      int fold_flag;
256
    } abstract;
257
    int lval;
258
    const char *opname;
259
  }
260
 
261
%type  exp exp1 type start start_opt operator colon_name
262
%type  unqualified_name colon_ext_name
263
%type  template template_arg
264
%type  builtin_type
265
%type  typespec_2 array_indicator
266
%type  colon_ext_only ext_only_name
267
 
268
%type  demangler_special function conversion_op
269
%type  conversion_op_name
270
 
271
%type  abstract_declarator direct_abstract_declarator
272
%type  abstract_declarator_fn
273
%type  declarator direct_declarator function_arglist
274
 
275
%type  declarator_1 direct_declarator_1
276
 
277
%type  template_params function_args
278
%type  ptr_operator
279
 
280
%type  nested_name
281
 
282
%type  qualifier qualifiers qualifiers_opt
283
 
284
%type  int_part int_seq
285
 
286
%token  INT
287
%token  FLOAT
288
 
289
%token  NAME
290
%type  name
291
 
292
%token STRUCT CLASS UNION ENUM SIZEOF UNSIGNED COLONCOLON
293
%token TEMPLATE
294
%token ERROR
295
%token NEW DELETE OPERATOR
296
%token STATIC_CAST REINTERPRET_CAST DYNAMIC_CAST
297
 
298
/* Special type cases, put in to allow the parser to distinguish different
299
   legal basetypes.  */
300
%token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD BOOL
301
%token ELLIPSIS RESTRICT VOID FLOAT_KEYWORD CHAR WCHAR_T
302
 
303
%token  ASSIGN_MODIFY
304
 
305
/* C++ */
306
%token TRUEKEYWORD
307
%token FALSEKEYWORD
308
 
309
/* Non-C++ things we get from the demangler.  */
310
%token  DEMANGLER_SPECIAL
311
%token CONSTRUCTION_VTABLE CONSTRUCTION_IN
312
 
313
/* Precedence declarations.  */
314
 
315
/* Give NAME lower precedence than COLONCOLON, so that nested_name will
316
   associate greedily.  */
317
%nonassoc NAME
318
 
319
/* Give NEW and DELETE lower precedence than ']', because we can not
320
   have an array of type operator new.  This causes NEW '[' to be
321
   parsed as operator new[].  */
322
%nonassoc NEW DELETE
323
 
324
/* Give VOID higher precedence than NAME.  Then we can use %prec NAME
325
   to prefer (VOID) to (function_args).  */
326
%nonassoc VOID
327
 
328
/* Give VOID lower precedence than ')' for similar reasons.  */
329
%nonassoc ')'
330
 
331
%left ','
332
%right '=' ASSIGN_MODIFY
333
%right '?'
334
%left OROR
335
%left ANDAND
336
%left '|'
337
%left '^'
338
%left '&'
339
%left EQUAL NOTEQUAL
340
%left '<' '>' LEQ GEQ
341
%left LSH RSH
342
%left '@'
343
%left '+' '-'
344
%left '*' '/' '%'
345
%right UNARY INCREMENT DECREMENT
346
 
347
/* We don't need a precedence for '(' in this reduced grammar, and it
348
   can mask some unpleasant bugs, so disable it for now.  */
349
 
350
%right ARROW '.' '[' /* '(' */
351
%left COLONCOLON
352
 
353
 
354
%%
355
 
356
result          :       start
357
                        { global_result = $1; }
358
                ;
359
 
360
start           :       type
361
 
362
                |       demangler_special
363
 
364
                |       function
365
 
366
                ;
367
 
368
start_opt       :       /* */
369
                        { $$ = NULL; }
370
                |       COLONCOLON start
371
                        { $$ = $2; }
372
                ;
373
 
374
function
375
                /* Function with a return type.  declarator_1 is used to prevent
376
                   ambiguity with the next rule.  */
377
                :       typespec_2 declarator_1
378
                        { $$ = $2.comp;
379
                          *$2.last = $1;
380
                        }
381
 
382
                /* Function without a return type.  We need to use typespec_2
383
                   to prevent conflicts from qualifiers_opt - harmless.  The
384
                   start_opt is used to handle "function-local" variables and
385
                   types.  */
386
                |       typespec_2 function_arglist start_opt
387
                        { $$ = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
388
                          if ($3) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $3); }
389
                |       colon_ext_only function_arglist start_opt
390
                        { $$ = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
391
                          if ($3) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $3); }
392
 
393
                |       conversion_op_name start_opt
394
                        { $$ = $1.comp;
395
                          if ($2) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $2); }
396
                |       conversion_op_name abstract_declarator_fn
397
                        { if ($2.last)
398
                            {
399
                               /* First complete the abstract_declarator's type using
400
                                  the typespec from the conversion_op_name.  */
401
                              *$2.last = *$1.last;
402
                              /* Then complete the conversion_op_name with the type.  */
403
                              *$1.last = $2.comp;
404
                            }
405
                          /* If we have an arglist, build a function type.  */
406
                          if ($2.fn.comp)
407
                            $$ = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1.comp, $2.fn.comp);
408
                          else
409
                            $$ = $1.comp;
410
                          if ($2.start) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $2.start);
411
                        }
412
                ;
413
 
414
demangler_special
415
                :       DEMANGLER_SPECIAL start
416
                        { $$ = make_empty ($1);
417
                          d_left ($$) = $2;
418
                          d_right ($$) = NULL; }
419
                |       CONSTRUCTION_VTABLE start CONSTRUCTION_IN start
420
                        { $$ = fill_comp (DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE, $2, $4); }
421
                ;
422
 
423
operator        :       OPERATOR NEW
424
                        { $$ = make_operator ("new", 1); }
425
                |       OPERATOR DELETE
426
                        { $$ = make_operator ("delete", 1); }
427
                |       OPERATOR NEW '[' ']'
428
                        { $$ = make_operator ("new[]", 1); }
429
                |       OPERATOR DELETE '[' ']'
430
                        { $$ = make_operator ("delete[]", 1); }
431
                |       OPERATOR '+'
432
                        { $$ = make_operator ("+", 2); }
433
                |       OPERATOR '-'
434
                        { $$ = make_operator ("-", 2); }
435
                |       OPERATOR '*'
436
                        { $$ = make_operator ("*", 2); }
437
                |       OPERATOR '/'
438
                        { $$ = make_operator ("/", 2); }
439
                |       OPERATOR '%'
440
                        { $$ = make_operator ("%", 2); }
441
                |       OPERATOR '^'
442
                        { $$ = make_operator ("^", 2); }
443
                |       OPERATOR '&'
444
                        { $$ = make_operator ("&", 2); }
445
                |       OPERATOR '|'
446
                        { $$ = make_operator ("|", 2); }
447
                |       OPERATOR '~'
448
                        { $$ = make_operator ("~", 1); }
449
                |       OPERATOR '!'
450
                        { $$ = make_operator ("!", 1); }
451
                |       OPERATOR '='
452
                        { $$ = make_operator ("=", 2); }
453
                |       OPERATOR '<'
454
                        { $$ = make_operator ("<", 2); }
455
                |       OPERATOR '>'
456
                        { $$ = make_operator (">", 2); }
457
                |       OPERATOR ASSIGN_MODIFY
458
                        { $$ = make_operator ($2, 2); }
459
                |       OPERATOR LSH
460
                        { $$ = make_operator ("<<", 2); }
461
                |       OPERATOR RSH
462
                        { $$ = make_operator (">>", 2); }
463
                |       OPERATOR EQUAL
464
                        { $$ = make_operator ("==", 2); }
465
                |       OPERATOR NOTEQUAL
466
                        { $$ = make_operator ("!=", 2); }
467
                |       OPERATOR LEQ
468
                        { $$ = make_operator ("<=", 2); }
469
                |       OPERATOR GEQ
470
                        { $$ = make_operator (">=", 2); }
471
                |       OPERATOR ANDAND
472
                        { $$ = make_operator ("&&", 2); }
473
                |       OPERATOR OROR
474
                        { $$ = make_operator ("||", 2); }
475
                |       OPERATOR INCREMENT
476
                        { $$ = make_operator ("++", 1); }
477
                |       OPERATOR DECREMENT
478
                        { $$ = make_operator ("--", 1); }
479
                |       OPERATOR ','
480
                        { $$ = make_operator (",", 2); }
481
                |       OPERATOR ARROW '*'
482
                        { $$ = make_operator ("->*", 2); }
483
                |       OPERATOR ARROW
484
                        { $$ = make_operator ("->", 2); }
485
                |       OPERATOR '(' ')'
486
                        { $$ = make_operator ("()", 2); }
487
                |       OPERATOR '[' ']'
488
                        { $$ = make_operator ("[]", 2); }
489
                ;
490
 
491
                /* Conversion operators.  We don't try to handle some of
492
                   the wackier demangler output for function pointers,
493
                   since it's not clear that it's parseable.  */
494
conversion_op
495
                :       OPERATOR typespec_2
496
                        { $$ = fill_comp (DEMANGLE_COMPONENT_CAST, $2, NULL); }
497
                ;
498
 
499
conversion_op_name
500
                :       nested_name conversion_op
501
                        { $$.comp = $1.comp;
502
                          d_right ($1.last) = $2;
503
                          $$.last = &d_left ($2);
504
                        }
505
                |       conversion_op
506
                        { $$.comp = $1;
507
                          $$.last = &d_left ($1);
508
                        }
509
                |       COLONCOLON nested_name conversion_op
510
                        { $$.comp = $2.comp;
511
                          d_right ($2.last) = $3;
512
                          $$.last = &d_left ($3);
513
                        }
514
                |       COLONCOLON conversion_op
515
                        { $$.comp = $2;
516
                          $$.last = &d_left ($2);
517
                        }
518
                ;
519
 
520
/* DEMANGLE_COMPONENT_NAME */
521
/* This accepts certain invalid placements of '~'.  */
522
unqualified_name:       operator
523
                |       operator '<' template_params '>'
524
                        { $$ = fill_comp (DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp); }
525
                |       '~' NAME
526
                        { $$ = make_dtor (gnu_v3_complete_object_dtor, $2); }
527
                ;
528
 
529
/* This rule is used in name and nested_name, and expanded inline there
530
   for efficiency.  */
531
/*
532
scope_id        :       NAME
533
                |       template
534
                ;
535
*/
536
 
537
colon_name      :       name
538
                |       COLONCOLON name
539
                        { $$ = $2; }
540
                ;
541
 
542
/* DEMANGLE_COMPONENT_QUAL_NAME */
543
/* DEMANGLE_COMPONENT_CTOR / DEMANGLE_COMPONENT_DTOR ? */
544
name            :       nested_name NAME %prec NAME
545
                        { $$ = $1.comp; d_right ($1.last) = $2; }
546
                |       NAME %prec NAME
547
                |       nested_name template %prec NAME
548
                        { $$ = $1.comp; d_right ($1.last) = $2; }
549
                |       template %prec NAME
550
                ;
551
 
552
colon_ext_name  :       colon_name
553
                |       colon_ext_only
554
                ;
555
 
556
colon_ext_only  :       ext_only_name
557
                |       COLONCOLON ext_only_name
558
                        { $$ = $2; }
559
                ;
560
 
561
ext_only_name   :       nested_name unqualified_name
562
                        { $$ = $1.comp; d_right ($1.last) = $2; }
563
                |       unqualified_name
564
                ;
565
 
566
nested_name     :       NAME COLONCOLON
567
                        { $$.comp = make_empty (DEMANGLE_COMPONENT_QUAL_NAME);
568
                          d_left ($$.comp) = $1;
569
                          d_right ($$.comp) = NULL;
570
                          $$.last = $$.comp;
571
                        }
572
                |       nested_name NAME COLONCOLON
573
                        { $$.comp = $1.comp;
574
                          d_right ($1.last) = make_empty (DEMANGLE_COMPONENT_QUAL_NAME);
575
                          $$.last = d_right ($1.last);
576
                          d_left ($$.last) = $2;
577
                          d_right ($$.last) = NULL;
578
                        }
579
                |       template COLONCOLON
580
                        { $$.comp = make_empty (DEMANGLE_COMPONENT_QUAL_NAME);
581
                          d_left ($$.comp) = $1;
582
                          d_right ($$.comp) = NULL;
583
                          $$.last = $$.comp;
584
                        }
585
                |       nested_name template COLONCOLON
586
                        { $$.comp = $1.comp;
587
                          d_right ($1.last) = make_empty (DEMANGLE_COMPONENT_QUAL_NAME);
588
                          $$.last = d_right ($1.last);
589
                          d_left ($$.last) = $2;
590
                          d_right ($$.last) = NULL;
591
                        }
592
                ;
593
 
594
/* DEMANGLE_COMPONENT_TEMPLATE */
595
/* DEMANGLE_COMPONENT_TEMPLATE_ARGLIST */
596
template        :       NAME '<' template_params '>'
597
                        { $$ = fill_comp (DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp); }
598
                ;
599
 
600
template_params :       template_arg
601
                        { $$.comp = fill_comp (DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, $1, NULL);
602
                        $$.last = &d_right ($$.comp); }
603
                |       template_params ',' template_arg
604
                        { $$.comp = $1.comp;
605
                          *$1.last = fill_comp (DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, $3, NULL);
606
                          $$.last = &d_right (*$1.last);
607
                        }
608
                ;
609
 
610
/* "type" is inlined into template_arg and function_args.  */
611
 
612
/* Also an integral constant-expression of integral type, and a
613
   pointer to member (?) */
614
template_arg    :       typespec_2
615
                |       typespec_2 abstract_declarator
616
                        { $$ = $2.comp;
617
                          *$2.last = $1;
618
                        }
619
                |       '&' start
620
                        { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator ("&", 1), $2); }
621
                |       '&' '(' start ')'
622
                        { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator ("&", 1), $3); }
623
                |       exp
624
                ;
625
 
626
function_args   :       typespec_2
627
                        { $$.comp = fill_comp (DEMANGLE_COMPONENT_ARGLIST, $1, NULL);
628
                          $$.last = &d_right ($$.comp);
629
                        }
630
                |       typespec_2 abstract_declarator
631
                        { *$2.last = $1;
632
                          $$.comp = fill_comp (DEMANGLE_COMPONENT_ARGLIST, $2.comp, NULL);
633
                          $$.last = &d_right ($$.comp);
634
                        }
635
                |       function_args ',' typespec_2
636
                        { *$1.last = fill_comp (DEMANGLE_COMPONENT_ARGLIST, $3, NULL);
637
                          $$.comp = $1.comp;
638
                          $$.last = &d_right (*$1.last);
639
                        }
640
                |       function_args ',' typespec_2 abstract_declarator
641
                        { *$4.last = $3;
642
                          *$1.last = fill_comp (DEMANGLE_COMPONENT_ARGLIST, $4.comp, NULL);
643
                          $$.comp = $1.comp;
644
                          $$.last = &d_right (*$1.last);
645
                        }
646
                |       function_args ',' ELLIPSIS
647
                        { *$1.last
648
                            = fill_comp (DEMANGLE_COMPONENT_ARGLIST,
649
                                           make_builtin_type ("..."),
650
                                           NULL);
651
                          $$.comp = $1.comp;
652
                          $$.last = &d_right (*$1.last);
653
                        }
654
                ;
655
 
656
function_arglist:       '(' function_args ')' qualifiers_opt %prec NAME
657
                        { $$.comp = fill_comp (DEMANGLE_COMPONENT_FUNCTION_TYPE, NULL, $2.comp);
658
                          $$.last = &d_left ($$.comp);
659
                          $$.comp = d_qualify ($$.comp, $4, 1); }
660
                |       '(' VOID ')' qualifiers_opt
661
                        { $$.comp = fill_comp (DEMANGLE_COMPONENT_FUNCTION_TYPE, NULL, NULL);
662
                          $$.last = &d_left ($$.comp);
663
                          $$.comp = d_qualify ($$.comp, $4, 1); }
664
                |       '(' ')' qualifiers_opt
665
                        { $$.comp = fill_comp (DEMANGLE_COMPONENT_FUNCTION_TYPE, NULL, NULL);
666
                          $$.last = &d_left ($$.comp);
667
                          $$.comp = d_qualify ($$.comp, $3, 1); }
668
                ;
669
 
670
/* Should do something about DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL */
671
qualifiers_opt  :       /* epsilon */
672
                        { $$ = 0; }
673
                |       qualifiers
674
                ;
675
 
676
qualifier       :       RESTRICT
677
                        { $$ = QUAL_RESTRICT; }
678
                |       VOLATILE_KEYWORD
679
                        { $$ = QUAL_VOLATILE; }
680
                |       CONST_KEYWORD
681
                        { $$ = QUAL_CONST; }
682
                ;
683
 
684
qualifiers      :       qualifier
685
                |       qualifier qualifiers
686
                        { $$ = $1 | $2; }
687
                ;
688
 
689
/* This accepts all sorts of invalid constructions and produces
690
   invalid output for them - an error would be better.  */
691
 
692
int_part        :       INT_KEYWORD
693
                        { $$ = 0; }
694
                |       SIGNED_KEYWORD
695
                        { $$ = INT_SIGNED; }
696
                |       UNSIGNED
697
                        { $$ = INT_UNSIGNED; }
698
                |       CHAR
699
                        { $$ = INT_CHAR; }
700
                |       LONG
701
                        { $$ = INT_LONG; }
702
                |       SHORT
703
                        { $$ = INT_SHORT; }
704
                ;
705
 
706
int_seq         :       int_part
707
                |       int_seq int_part
708
                        { $$ = $1 | $2; if ($1 & $2 & INT_LONG) $$ = $1 | INT_LLONG; }
709
                ;
710
 
711
builtin_type    :       int_seq
712
                        { $$ = d_int_type ($1); }
713
                |       FLOAT_KEYWORD
714
                        { $$ = make_builtin_type ("float"); }
715
                |       DOUBLE_KEYWORD
716
                        { $$ = make_builtin_type ("double"); }
717
                |       LONG DOUBLE_KEYWORD
718
                        { $$ = make_builtin_type ("long double"); }
719
                |       BOOL
720
                        { $$ = make_builtin_type ("bool"); }
721
                |       WCHAR_T
722
                        { $$ = make_builtin_type ("wchar_t"); }
723
                |       VOID
724
                        { $$ = make_builtin_type ("void"); }
725
                ;
726
 
727
ptr_operator    :       '*' qualifiers_opt
728
                        { $$.comp = make_empty (DEMANGLE_COMPONENT_POINTER);
729
                          $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
730
                          $$.last = &d_left ($$.comp);
731
                          $$.comp = d_qualify ($$.comp, $2, 0); }
732
                /* g++ seems to allow qualifiers after the reference?  */
733
                |       '&'
734
                        { $$.comp = make_empty (DEMANGLE_COMPONENT_REFERENCE);
735
                          $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
736
                          $$.last = &d_left ($$.comp); }
737
                |       nested_name '*' qualifiers_opt
738
                        { $$.comp = make_empty (DEMANGLE_COMPONENT_PTRMEM_TYPE);
739
                          $$.comp->u.s_binary.left = $1.comp;
740
                          /* Convert the innermost DEMANGLE_COMPONENT_QUAL_NAME to a DEMANGLE_COMPONENT_NAME.  */
741
                          *$1.last = *d_left ($1.last);
742
                          $$.comp->u.s_binary.right = NULL;
743
                          $$.last = &d_right ($$.comp);
744
                          $$.comp = d_qualify ($$.comp, $3, 0); }
745
                |       COLONCOLON nested_name '*' qualifiers_opt
746
                        { $$.comp = make_empty (DEMANGLE_COMPONENT_PTRMEM_TYPE);
747
                          $$.comp->u.s_binary.left = $2.comp;
748
                          /* Convert the innermost DEMANGLE_COMPONENT_QUAL_NAME to a DEMANGLE_COMPONENT_NAME.  */
749
                          *$2.last = *d_left ($2.last);
750
                          $$.comp->u.s_binary.right = NULL;
751
                          $$.last = &d_right ($$.comp);
752
                          $$.comp = d_qualify ($$.comp, $4, 0); }
753
                ;
754
 
755
array_indicator :       '[' ']'
756
                        { $$ = make_empty (DEMANGLE_COMPONENT_ARRAY_TYPE);
757
                          d_left ($$) = NULL;
758
                        }
759
                |       '[' INT ']'
760
                        { $$ = make_empty (DEMANGLE_COMPONENT_ARRAY_TYPE);
761
                          d_left ($$) = $2;
762
                        }
763
                ;
764
 
765
/* Details of this approach inspired by the G++ < 3.4 parser.  */
766
 
767
/* This rule is only used in typespec_2, and expanded inline there for
768
   efficiency.  */
769
/*
770
typespec        :       builtin_type
771
                |       colon_name
772
                ;
773
*/
774
 
775
typespec_2      :       builtin_type qualifiers
776
                        { $$ = d_qualify ($1, $2, 0); }
777
                |       builtin_type
778
                |       qualifiers builtin_type qualifiers
779
                        { $$ = d_qualify ($2, $1 | $3, 0); }
780
                |       qualifiers builtin_type
781
                        { $$ = d_qualify ($2, $1, 0); }
782
 
783
                |       name qualifiers
784
                        { $$ = d_qualify ($1, $2, 0); }
785
                |       name
786
                |       qualifiers name qualifiers
787
                        { $$ = d_qualify ($2, $1 | $3, 0); }
788
                |       qualifiers name
789
                        { $$ = d_qualify ($2, $1, 0); }
790
 
791
                |       COLONCOLON name qualifiers
792
                        { $$ = d_qualify ($2, $3, 0); }
793
                |       COLONCOLON name
794
                        { $$ = $2; }
795
                |       qualifiers COLONCOLON name qualifiers
796
                        { $$ = d_qualify ($3, $1 | $4, 0); }
797
                |       qualifiers COLONCOLON name
798
                        { $$ = d_qualify ($3, $1, 0); }
799
                ;
800
 
801
abstract_declarator
802
                :       ptr_operator
803
                        { $$.comp = $1.comp; $$.last = $1.last;
804
                          $$.fn.comp = NULL; $$.fn.last = NULL; }
805
                |       ptr_operator abstract_declarator
806
                        { $$ = $2; $$.fn.comp = NULL; $$.fn.last = NULL;
807
                          if ($2.fn.comp) { $$.last = $2.fn.last; *$2.last = $2.fn.comp; }
808
                          *$$.last = $1.comp;
809
                          $$.last = $1.last; }
810
                |       direct_abstract_declarator
811
                        { $$.fn.comp = NULL; $$.fn.last = NULL;
812
                          if ($1.fn.comp) { $$.last = $1.fn.last; *$1.last = $1.fn.comp; }
813
                        }
814
                ;
815
 
816
direct_abstract_declarator
817
                :       '(' abstract_declarator ')'
818
                        { $$ = $2; $$.fn.comp = NULL; $$.fn.last = NULL; $$.fold_flag = 1;
819
                          if ($2.fn.comp) { $$.last = $2.fn.last; *$2.last = $2.fn.comp; }
820
                        }
821
                |       direct_abstract_declarator function_arglist
822
                        { $$.fold_flag = 0;
823
                          if ($1.fn.comp) { $$.last = $1.fn.last; *$1.last = $1.fn.comp; }
824
                          if ($1.fold_flag)
825
                            {
826
                              *$$.last = $2.comp;
827
                              $$.last = $2.last;
828
                            }
829
                          else
830
                            $$.fn = $2;
831
                        }
832
                |       direct_abstract_declarator array_indicator
833
                        { $$.fn.comp = NULL; $$.fn.last = NULL; $$.fold_flag = 0;
834
                          if ($1.fn.comp) { $$.last = $1.fn.last; *$1.last = $1.fn.comp; }
835
                          *$1.last = $2;
836
                          $$.last = &d_right ($2);
837
                        }
838
                |       array_indicator
839
                        { $$.fn.comp = NULL; $$.fn.last = NULL; $$.fold_flag = 0;
840
                          $$.comp = $1;
841
                          $$.last = &d_right ($1);
842
                        }
843
                /* G++ has the following except for () and (type).  Then
844
                   (type) is handled in regcast_or_absdcl and () is handled
845
                   in fcast_or_absdcl.
846
 
847
                   However, this is only useful for function types, and
848
                   generates reduce/reduce conflicts with direct_declarator.
849
                   We're interested in pointer-to-function types, and in
850
                   functions, but not in function types - so leave this
851
                   out.  */
852
                /* |    function_arglist */
853
                ;
854
 
855
abstract_declarator_fn
856
                :       ptr_operator
857
                        { $$.comp = $1.comp; $$.last = $1.last;
858
                          $$.fn.comp = NULL; $$.fn.last = NULL; $$.start = NULL; }
859
                |       ptr_operator abstract_declarator_fn
860
                        { $$ = $2;
861
                          if ($2.last)
862
                            *$$.last = $1.comp;
863
                          else
864
                            $$.comp = $1.comp;
865
                          $$.last = $1.last;
866
                        }
867
                |       direct_abstract_declarator
868
                        { $$.comp = $1.comp; $$.last = $1.last; $$.fn = $1.fn; $$.start = NULL; }
869
                |       direct_abstract_declarator function_arglist COLONCOLON start
870
                        { $$.start = $4;
871
                          if ($1.fn.comp) { $$.last = $1.fn.last; *$1.last = $1.fn.comp; }
872
                          if ($1.fold_flag)
873
                            {
874
                              *$$.last = $2.comp;
875
                              $$.last = $2.last;
876
                            }
877
                          else
878
                            $$.fn = $2;
879
                        }
880
                |       function_arglist start_opt
881
                        { $$.fn = $1;
882
                          $$.start = $2;
883
                          $$.comp = NULL; $$.last = NULL;
884
                        }
885
                ;
886
 
887
type            :       typespec_2
888
                |       typespec_2 abstract_declarator
889
                        { $$ = $2.comp;
890
                          *$2.last = $1;
891
                        }
892
                ;
893
 
894
declarator      :       ptr_operator declarator
895
                        { $$.comp = $2.comp;
896
                          $$.last = $1.last;
897
                          *$2.last = $1.comp; }
898
                |       direct_declarator
899
                ;
900
 
901
direct_declarator
902
                :       '(' declarator ')'
903
                        { $$ = $2; }
904
                |       direct_declarator function_arglist
905
                        { $$.comp = $1.comp;
906
                          *$1.last = $2.comp;
907
                          $$.last = $2.last;
908
                        }
909
                |       direct_declarator array_indicator
910
                        { $$.comp = $1.comp;
911
                          *$1.last = $2;
912
                          $$.last = &d_right ($2);
913
                        }
914
                |       colon_ext_name
915
                        { $$.comp = make_empty (DEMANGLE_COMPONENT_TYPED_NAME);
916
                          d_left ($$.comp) = $1;
917
                          $$.last = &d_right ($$.comp);
918
                        }
919
                ;
920
 
921
/* These are similar to declarator and direct_declarator except that they
922
   do not permit ( colon_ext_name ), which is ambiguous with a function
923
   argument list.  They also don't permit a few other forms with redundant
924
   parentheses around the colon_ext_name; any colon_ext_name in parentheses
925
   must be followed by an argument list or an array indicator, or preceded
926
   by a pointer.  */
927
declarator_1    :       ptr_operator declarator_1
928
                        { $$.comp = $2.comp;
929
                          $$.last = $1.last;
930
                          *$2.last = $1.comp; }
931
                |       colon_ext_name
932
                        { $$.comp = make_empty (DEMANGLE_COMPONENT_TYPED_NAME);
933
                          d_left ($$.comp) = $1;
934
                          $$.last = &d_right ($$.comp);
935
                        }
936
                |       direct_declarator_1
937
 
938
                        /* Function local variable or type.  The typespec to
939
                           our left is the type of the containing function.
940
                           This should be OK, because function local types
941
                           can not be templates, so the return types of their
942
                           members will not be mangled.  If they are hopefully
943
                           they'll end up to the right of the ::.  */
944
                |       colon_ext_name function_arglist COLONCOLON start
945
                        { $$.comp = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
946
                          $$.last = $2.last;
947
                          $$.comp = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$.comp, $4);
948
                        }
949
                |       direct_declarator_1 function_arglist COLONCOLON start
950
                        { $$.comp = $1.comp;
951
                          *$1.last = $2.comp;
952
                          $$.last = $2.last;
953
                          $$.comp = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$.comp, $4);
954
                        }
955
                ;
956
 
957
direct_declarator_1
958
                :       '(' ptr_operator declarator ')'
959
                        { $$.comp = $3.comp;
960
                          $$.last = $2.last;
961
                          *$3.last = $2.comp; }
962
                |       direct_declarator_1 function_arglist
963
                        { $$.comp = $1.comp;
964
                          *$1.last = $2.comp;
965
                          $$.last = $2.last;
966
                        }
967
                |       direct_declarator_1 array_indicator
968
                        { $$.comp = $1.comp;
969
                          *$1.last = $2;
970
                          $$.last = &d_right ($2);
971
                        }
972
                |       colon_ext_name function_arglist
973
                        { $$.comp = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
974
                          $$.last = $2.last;
975
                        }
976
                |       colon_ext_name array_indicator
977
                        { $$.comp = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2);
978
                          $$.last = &d_right ($2);
979
                        }
980
                ;
981
 
982
exp     :       '(' exp1 ')'
983
                { $$ = $2; }
984
        ;
985
 
986
/* Silly trick.  Only allow '>' when parenthesized, in order to
987
   handle conflict with templates.  */
988
exp1    :       exp
989
        ;
990
 
991
exp1    :       exp '>' exp
992
                { $$ = d_binary (">", $1, $3); }
993
        ;
994
 
995
/* References.  Not allowed everywhere in template parameters, only
996
   at the top level, but treat them as expressions in case they are wrapped
997
   in parentheses.  */
998
exp1    :       '&' start
999
                { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator ("&", 1), $2); }
1000
        |       '&' '(' start ')'
1001
                { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator ("&", 1), $3); }
1002
        ;
1003
 
1004
/* Expressions, not including the comma operator.  */
1005
exp     :       '-' exp    %prec UNARY
1006
                { $$ = d_unary ("-", $2); }
1007
        ;
1008
 
1009
exp     :       '!' exp    %prec UNARY
1010
                { $$ = d_unary ("!", $2); }
1011
        ;
1012
 
1013
exp     :       '~' exp    %prec UNARY
1014
                { $$ = d_unary ("~", $2); }
1015
        ;
1016
 
1017
/* Casts.  First your normal C-style cast.  If exp is a LITERAL, just change
1018
   its type.  */
1019
 
1020
exp     :       '(' type ')' exp  %prec UNARY
1021
                { if ($4->type == DEMANGLE_COMPONENT_LITERAL
1022
                      || $4->type == DEMANGLE_COMPONENT_LITERAL_NEG)
1023
                    {
1024
                      $$ = $4;
1025
                      d_left ($4) = $2;
1026
                    }
1027
                  else
1028
                    $$ = fill_comp (DEMANGLE_COMPONENT_UNARY,
1029
                                      fill_comp (DEMANGLE_COMPONENT_CAST, $2, NULL),
1030
                                      $4);
1031
                }
1032
        ;
1033
 
1034
/* Mangling does not differentiate between these, so we don't need to
1035
   either.  */
1036
exp     :       STATIC_CAST '<' type '>' '(' exp1 ')' %prec UNARY
1037
                { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY,
1038
                                    fill_comp (DEMANGLE_COMPONENT_CAST, $3, NULL),
1039
                                    $6);
1040
                }
1041
        ;
1042
 
1043
exp     :       DYNAMIC_CAST '<' type '>' '(' exp1 ')' %prec UNARY
1044
                { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY,
1045
                                    fill_comp (DEMANGLE_COMPONENT_CAST, $3, NULL),
1046
                                    $6);
1047
                }
1048
        ;
1049
 
1050
exp     :       REINTERPRET_CAST '<' type '>' '(' exp1 ')' %prec UNARY
1051
                { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY,
1052
                                    fill_comp (DEMANGLE_COMPONENT_CAST, $3, NULL),
1053
                                    $6);
1054
                }
1055
        ;
1056
 
1057
/* Another form of C++-style cast is "type ( exp1 )".  This creates too many
1058
   conflicts to support.  For a while we supported the simpler
1059
   "typespec_2 ( exp1 )", but that conflicts with "& ( start )" as a
1060
   reference, deep within the wilderness of abstract declarators:
1061
   Qux vs Qux, a shift-reduce conflict at the
1062
   innermost left parenthesis.  So we do not support function-like casts.
1063
   Fortunately they never appear in demangler output.  */
1064
 
1065
/* TO INVESTIGATE: ._0 style anonymous names; anonymous namespaces */
1066
 
1067
/* Binary operators in order of decreasing precedence.  */
1068
 
1069
exp     :       exp '*' exp
1070
                { $$ = d_binary ("*", $1, $3); }
1071
        ;
1072
 
1073
exp     :       exp '/' exp
1074
                { $$ = d_binary ("/", $1, $3); }
1075
        ;
1076
 
1077
exp     :       exp '%' exp
1078
                { $$ = d_binary ("%", $1, $3); }
1079
        ;
1080
 
1081
exp     :       exp '+' exp
1082
                { $$ = d_binary ("+", $1, $3); }
1083
        ;
1084
 
1085
exp     :       exp '-' exp
1086
                { $$ = d_binary ("-", $1, $3); }
1087
        ;
1088
 
1089
exp     :       exp LSH exp
1090
                { $$ = d_binary ("<<", $1, $3); }
1091
        ;
1092
 
1093
exp     :       exp RSH exp
1094
                { $$ = d_binary (">>", $1, $3); }
1095
        ;
1096
 
1097
exp     :       exp EQUAL exp
1098
                { $$ = d_binary ("==", $1, $3); }
1099
        ;
1100
 
1101
exp     :       exp NOTEQUAL exp
1102
                { $$ = d_binary ("!=", $1, $3); }
1103
        ;
1104
 
1105
exp     :       exp LEQ exp
1106
                { $$ = d_binary ("<=", $1, $3); }
1107
        ;
1108
 
1109
exp     :       exp GEQ exp
1110
                { $$ = d_binary (">=", $1, $3); }
1111
        ;
1112
 
1113
exp     :       exp '<' exp
1114
                { $$ = d_binary ("<", $1, $3); }
1115
        ;
1116
 
1117
exp     :       exp '&' exp
1118
                { $$ = d_binary ("&", $1, $3); }
1119
        ;
1120
 
1121
exp     :       exp '^' exp
1122
                { $$ = d_binary ("^", $1, $3); }
1123
        ;
1124
 
1125
exp     :       exp '|' exp
1126
                { $$ = d_binary ("|", $1, $3); }
1127
        ;
1128
 
1129
exp     :       exp ANDAND exp
1130
                { $$ = d_binary ("&&", $1, $3); }
1131
        ;
1132
 
1133
exp     :       exp OROR exp
1134
                { $$ = d_binary ("||", $1, $3); }
1135
        ;
1136
 
1137
/* Not 100% sure these are necessary, but they're harmless.  */
1138
exp     :       exp ARROW NAME
1139
                { $$ = d_binary ("->", $1, $3); }
1140
        ;
1141
 
1142
exp     :       exp '.' NAME
1143
                { $$ = d_binary (".", $1, $3); }
1144
        ;
1145
 
1146
exp     :       exp '?' exp ':' exp     %prec '?'
1147
                { $$ = fill_comp (DEMANGLE_COMPONENT_TRINARY, make_operator ("?", 3),
1148
                                    fill_comp (DEMANGLE_COMPONENT_TRINARY_ARG1, $1,
1149
                                                 fill_comp (DEMANGLE_COMPONENT_TRINARY_ARG2, $3, $5)));
1150
                }
1151
        ;
1152
 
1153
exp     :       INT
1154
        ;
1155
 
1156
/* Not generally allowed.  */
1157
exp     :       FLOAT
1158
        ;
1159
 
1160
exp     :       SIZEOF '(' type ')'     %prec UNARY
1161
                { $$ = d_unary ("sizeof", $3); }
1162
        ;
1163
 
1164
/* C++.  */
1165
exp     :       TRUEKEYWORD
1166
                { struct demangle_component *i;
1167
                  i = make_name ("1", 1);
1168
                  $$ = fill_comp (DEMANGLE_COMPONENT_LITERAL,
1169
                                    make_builtin_type ("bool"),
1170
                                    i);
1171
                }
1172
        ;
1173
 
1174
exp     :       FALSEKEYWORD
1175
                { struct demangle_component *i;
1176
                  i = make_name ("0", 1);
1177
                  $$ = fill_comp (DEMANGLE_COMPONENT_LITERAL,
1178
                                    make_builtin_type ("bool"),
1179
                                    i);
1180
                }
1181
        ;
1182
 
1183
/* end of C++.  */
1184
 
1185
%%
1186
 
1187
/* Apply QUALIFIERS to LHS and return a qualified component.  IS_METHOD
1188
   is set if LHS is a method, in which case the qualifiers are logically
1189
   applied to "this".  We apply qualifiers in a consistent order; LHS
1190
   may already be qualified; duplicate qualifiers are not created.  */
1191
 
1192
struct demangle_component *
1193
d_qualify (struct demangle_component *lhs, int qualifiers, int is_method)
1194
{
1195
  struct demangle_component **inner_p;
1196
  enum demangle_component_type type;
1197
 
1198
  /* For now the order is CONST (innermost), VOLATILE, RESTRICT.  */
1199
 
1200
#define HANDLE_QUAL(TYPE, MTYPE, QUAL)                          \
1201
  if ((qualifiers & QUAL) && (type != TYPE) && (type != MTYPE)) \
1202
    {                                                           \
1203
      *inner_p = fill_comp (is_method ? MTYPE : TYPE,   \
1204
                              *inner_p, NULL);                  \
1205
      inner_p = &d_left (*inner_p);                               \
1206
      type = (*inner_p)->type;                                  \
1207
    }                                                           \
1208
  else if (type == TYPE || type == MTYPE)                       \
1209
    {                                                           \
1210
      inner_p = &d_left (*inner_p);                               \
1211
      type = (*inner_p)->type;                                  \
1212
    }
1213
 
1214
  inner_p = &lhs;
1215
 
1216
  type = (*inner_p)->type;
1217
 
1218
  HANDLE_QUAL (DEMANGLE_COMPONENT_RESTRICT, DEMANGLE_COMPONENT_RESTRICT_THIS, QUAL_RESTRICT);
1219
  HANDLE_QUAL (DEMANGLE_COMPONENT_VOLATILE, DEMANGLE_COMPONENT_VOLATILE_THIS, QUAL_VOLATILE);
1220
  HANDLE_QUAL (DEMANGLE_COMPONENT_CONST, DEMANGLE_COMPONENT_CONST_THIS, QUAL_CONST);
1221
 
1222
  return lhs;
1223
}
1224
 
1225
/* Return a builtin type corresponding to FLAGS.  */
1226
 
1227
static struct demangle_component *
1228
d_int_type (int flags)
1229
{
1230
  const char *name;
1231
 
1232
  switch (flags)
1233
    {
1234
    case INT_SIGNED | INT_CHAR:
1235
      name = "signed char";
1236
      break;
1237
    case INT_CHAR:
1238
      name = "char";
1239
      break;
1240
    case INT_UNSIGNED | INT_CHAR:
1241
      name = "unsigned char";
1242
      break;
1243
    case 0:
1244
    case INT_SIGNED:
1245
      name = "int";
1246
      break;
1247
    case INT_UNSIGNED:
1248
      name = "unsigned int";
1249
      break;
1250
    case INT_LONG:
1251
    case INT_SIGNED | INT_LONG:
1252
      name = "long";
1253
      break;
1254
    case INT_UNSIGNED | INT_LONG:
1255
      name = "unsigned long";
1256
      break;
1257
    case INT_SHORT:
1258
    case INT_SIGNED | INT_SHORT:
1259
      name = "short";
1260
      break;
1261
    case INT_UNSIGNED | INT_SHORT:
1262
      name = "unsigned short";
1263
      break;
1264
    case INT_LLONG | INT_LONG:
1265
    case INT_SIGNED | INT_LLONG | INT_LONG:
1266
      name = "long long";
1267
      break;
1268
    case INT_UNSIGNED | INT_LLONG | INT_LONG:
1269
      name = "unsigned long long";
1270
      break;
1271
    default:
1272
      return NULL;
1273
    }
1274
 
1275
  return make_builtin_type (name);
1276
}
1277
 
1278
/* Wrapper to create a unary operation.  */
1279
 
1280
static struct demangle_component *
1281
d_unary (const char *name, struct demangle_component *lhs)
1282
{
1283
  return fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator (name, 1), lhs);
1284
}
1285
 
1286
/* Wrapper to create a binary operation.  */
1287
 
1288
static struct demangle_component *
1289
d_binary (const char *name, struct demangle_component *lhs, struct demangle_component *rhs)
1290
{
1291
  return fill_comp (DEMANGLE_COMPONENT_BINARY, make_operator (name, 2),
1292
                      fill_comp (DEMANGLE_COMPONENT_BINARY_ARGS, lhs, rhs));
1293
}
1294
 
1295
/* Find the end of a symbol name starting at LEXPTR.  */
1296
 
1297
static const char *
1298
symbol_end (const char *lexptr)
1299
{
1300
  const char *p = lexptr;
1301
 
1302
  while (*p && (ISALNUM (*p) || *p == '_' || *p == '$' || *p == '.'))
1303
    p++;
1304
 
1305
  return p;
1306
}
1307
 
1308
/* Take care of parsing a number (anything that starts with a digit).
1309
   The number starts at P and contains LEN characters.  Store the result in
1310
   YYLVAL.  */
1311
 
1312
static int
1313
parse_number (const char *p, int len, int parsed_float)
1314
{
1315
  int unsigned_p = 0;
1316
 
1317
  /* Number of "L" suffixes encountered.  */
1318
  int long_p = 0;
1319
 
1320
  struct demangle_component *signed_type;
1321
  struct demangle_component *unsigned_type;
1322
  struct demangle_component *type, *name;
1323
  enum demangle_component_type literal_type;
1324
 
1325
  if (p[0] == '-')
1326
    {
1327
      literal_type = DEMANGLE_COMPONENT_LITERAL_NEG;
1328
      p++;
1329
      len--;
1330
    }
1331
  else
1332
    literal_type = DEMANGLE_COMPONENT_LITERAL;
1333
 
1334
  if (parsed_float)
1335
    {
1336
      /* It's a float since it contains a point or an exponent.  */
1337
      char c;
1338
 
1339
      /* The GDB lexer checks the result of scanf at this point.  Not doing
1340
         this leaves our error checking slightly weaker but only for invalid
1341
         data.  */
1342
 
1343
      /* See if it has `f' or `l' suffix (float or long double).  */
1344
 
1345
      c = TOLOWER (p[len - 1]);
1346
 
1347
      if (c == 'f')
1348
        {
1349
          len--;
1350
          type = make_builtin_type ("float");
1351
        }
1352
      else if (c == 'l')
1353
        {
1354
          len--;
1355
          type = make_builtin_type ("long double");
1356
        }
1357
      else if (ISDIGIT (c) || c == '.')
1358
        type = make_builtin_type ("double");
1359
      else
1360
        return ERROR;
1361
 
1362
      name = make_name (p, len);
1363
      yylval.comp = fill_comp (literal_type, type, name);
1364
 
1365
      return FLOAT;
1366
    }
1367
 
1368
  /* This treats 0x1 and 1 as different literals.  We also do not
1369
     automatically generate unsigned types.  */
1370
 
1371
  long_p = 0;
1372
  unsigned_p = 0;
1373
  while (len > 0)
1374
    {
1375
      if (p[len - 1] == 'l' || p[len - 1] == 'L')
1376
        {
1377
          len--;
1378
          long_p++;
1379
          continue;
1380
        }
1381
      if (p[len - 1] == 'u' || p[len - 1] == 'U')
1382
        {
1383
          len--;
1384
          unsigned_p++;
1385
          continue;
1386
        }
1387
      break;
1388
    }
1389
 
1390
  if (long_p == 0)
1391
    {
1392
      unsigned_type = make_builtin_type ("unsigned int");
1393
      signed_type = make_builtin_type ("int");
1394
    }
1395
  else if (long_p == 1)
1396
    {
1397
      unsigned_type = make_builtin_type ("unsigned long");
1398
      signed_type = make_builtin_type ("long");
1399
    }
1400
  else
1401
    {
1402
      unsigned_type = make_builtin_type ("unsigned long long");
1403
      signed_type = make_builtin_type ("long long");
1404
    }
1405
 
1406
   if (unsigned_p)
1407
     type = unsigned_type;
1408
   else
1409
     type = signed_type;
1410
 
1411
   name = make_name (p, len);
1412
   yylval.comp = fill_comp (literal_type, type, name);
1413
 
1414
   return INT;
1415
}
1416
 
1417
static char backslashable[] = "abefnrtv";
1418
static char represented[] = "\a\b\e\f\n\r\t\v";
1419
 
1420
/* Translate the backslash the way we would in the host character set.  */
1421
static int
1422
c_parse_backslash (int host_char, int *target_char)
1423
{
1424
  const char *ix;
1425
  ix = strchr (backslashable, host_char);
1426
  if (! ix)
1427
    return 0;
1428
  else
1429
    *target_char = represented[ix - backslashable];
1430
  return 1;
1431
}
1432
 
1433
/* Parse a C escape sequence.  STRING_PTR points to a variable
1434
   containing a pointer to the string to parse.  That pointer
1435
   should point to the character after the \.  That pointer
1436
   is updated past the characters we use.  The value of the
1437
   escape sequence is returned.
1438
 
1439
   A negative value means the sequence \ newline was seen,
1440
   which is supposed to be equivalent to nothing at all.
1441
 
1442
   If \ is followed by a null character, we return a negative
1443
   value and leave the string pointer pointing at the null character.
1444
 
1445
   If \ is followed by 000, we return 0 and leave the string pointer
1446
   after the zeros.  A value of 0 does not mean end of string.  */
1447
 
1448
static int
1449
cp_parse_escape (const char **string_ptr)
1450
{
1451
  int target_char;
1452
  int c = *(*string_ptr)++;
1453
  if (c_parse_backslash (c, &target_char))
1454
    return target_char;
1455
  else
1456
    switch (c)
1457
      {
1458
      case '\n':
1459
        return -2;
1460
      case 0:
1461
        (*string_ptr)--;
1462
        return 0;
1463
      case '^':
1464
        {
1465
          c = *(*string_ptr)++;
1466
 
1467
          if (c == '?')
1468
            return 0177;
1469
          else if (c == '\\')
1470
            target_char = cp_parse_escape (string_ptr);
1471
          else
1472
            target_char = c;
1473
 
1474
          /* Now target_char is something like `c', and we want to find
1475
             its control-character equivalent.  */
1476
          target_char = target_char & 037;
1477
 
1478
          return target_char;
1479
        }
1480
 
1481
      case '0':
1482
      case '1':
1483
      case '2':
1484
      case '3':
1485
      case '4':
1486
      case '5':
1487
      case '6':
1488
      case '7':
1489
        {
1490
          int i = c - '0';
1491
          int count = 0;
1492
          while (++count < 3)
1493
            {
1494
              c = (**string_ptr);
1495
              if (c >= '0' && c <= '7')
1496
                {
1497
                  (*string_ptr)++;
1498
                  i *= 8;
1499
                  i += c - '0';
1500
                }
1501
              else
1502
                {
1503
                  break;
1504
                }
1505
            }
1506
          return i;
1507
        }
1508
      default:
1509
        return c;
1510
      }
1511
}
1512
 
1513
#define HANDLE_SPECIAL(string, comp)                            \
1514
  if (strncmp (tokstart, string, sizeof (string) - 1) == 0)     \
1515
    {                                                           \
1516
      lexptr = tokstart + sizeof (string) - 1;                  \
1517
      yylval.lval = comp;                                       \
1518
      return DEMANGLER_SPECIAL;                                 \
1519
    }
1520
 
1521
#define HANDLE_TOKEN2(string, token)                    \
1522
  if (lexptr[1] == string[1])                           \
1523
    {                                                   \
1524
      lexptr += 2;                                      \
1525
      yylval.opname = string;                           \
1526
      return token;                                     \
1527
    }
1528
 
1529
#define HANDLE_TOKEN3(string, token)                    \
1530
  if (lexptr[1] == string[1] && lexptr[2] == string[2]) \
1531
    {                                                   \
1532
      lexptr += 3;                                      \
1533
      yylval.opname = string;                           \
1534
      return token;                                     \
1535
    }
1536
 
1537
/* Read one token, getting characters through LEXPTR.  */
1538
 
1539
static int
1540
yylex (void)
1541
{
1542
  int c;
1543
  int namelen;
1544
  const char *tokstart, *tokptr;
1545
 
1546
 retry:
1547
  prev_lexptr = lexptr;
1548
  tokstart = lexptr;
1549
 
1550
  switch (c = *tokstart)
1551
    {
1552
    case 0:
1553
      return 0;
1554
 
1555
    case ' ':
1556
    case '\t':
1557
    case '\n':
1558
      lexptr++;
1559
      goto retry;
1560
 
1561
    case '\'':
1562
      /* We either have a character constant ('0' or '\177' for example)
1563
         or we have a quoted symbol reference ('foo(int,int)' in C++
1564
         for example). */
1565
      lexptr++;
1566
      c = *lexptr++;
1567
      if (c == '\\')
1568
        c = cp_parse_escape (&lexptr);
1569
      else if (c == '\'')
1570
        {
1571
          yyerror ("empty character constant");
1572
          return ERROR;
1573
        }
1574
 
1575
      c = *lexptr++;
1576
      if (c != '\'')
1577
        {
1578
          yyerror ("invalid character constant");
1579
          return ERROR;
1580
        }
1581
 
1582
      /* FIXME: We should refer to a canonical form of the character,
1583
         presumably the same one that appears in manglings - the decimal
1584
         representation.  But if that isn't in our input then we have to
1585
         allocate memory for it somewhere.  */
1586
      yylval.comp = fill_comp (DEMANGLE_COMPONENT_LITERAL,
1587
                                 make_builtin_type ("char"),
1588
                                 make_name (tokstart, lexptr - tokstart));
1589
 
1590
      return INT;
1591
 
1592
    case '(':
1593
      if (strncmp (tokstart, "(anonymous namespace)", 21) == 0)
1594
        {
1595
          lexptr += 21;
1596
          yylval.comp = make_name ("(anonymous namespace)",
1597
                                     sizeof "(anonymous namespace)" - 1);
1598
          return NAME;
1599
        }
1600
        /* FALL THROUGH */
1601
 
1602
    case ')':
1603
    case ',':
1604
      lexptr++;
1605
      return c;
1606
 
1607
    case '.':
1608
      if (lexptr[1] == '.' && lexptr[2] == '.')
1609
        {
1610
          lexptr += 3;
1611
          return ELLIPSIS;
1612
        }
1613
 
1614
      /* Might be a floating point number.  */
1615
      if (lexptr[1] < '0' || lexptr[1] > '9')
1616
        goto symbol;            /* Nope, must be a symbol. */
1617
 
1618
      goto try_number;
1619
 
1620
    case '-':
1621
      HANDLE_TOKEN2 ("-=", ASSIGN_MODIFY);
1622
      HANDLE_TOKEN2 ("--", DECREMENT);
1623
      HANDLE_TOKEN2 ("->", ARROW);
1624
 
1625
      /* For construction vtables.  This is kind of hokey.  */
1626
      if (strncmp (tokstart, "-in-", 4) == 0)
1627
        {
1628
          lexptr += 4;
1629
          return CONSTRUCTION_IN;
1630
        }
1631
 
1632
      if (lexptr[1] < '0' || lexptr[1] > '9')
1633
        {
1634
          lexptr++;
1635
          return '-';
1636
        }
1637
      /* FALL THRU into number case.  */
1638
 
1639
    try_number:
1640
    case '0':
1641
    case '1':
1642
    case '2':
1643
    case '3':
1644
    case '4':
1645
    case '5':
1646
    case '6':
1647
    case '7':
1648
    case '8':
1649
    case '9':
1650
      {
1651
        /* It's a number.  */
1652
        int got_dot = 0, got_e = 0, toktype;
1653
        const char *p = tokstart;
1654
        int hex = 0;
1655
 
1656
        if (c == '-')
1657
          p++;
1658
 
1659
        if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
1660
          {
1661
            p += 2;
1662
            hex = 1;
1663
          }
1664
        else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
1665
          {
1666
            p += 2;
1667
            hex = 0;
1668
          }
1669
 
1670
        for (;; ++p)
1671
          {
1672
            /* This test includes !hex because 'e' is a valid hex digit
1673
               and thus does not indicate a floating point number when
1674
               the radix is hex.  */
1675
            if (!hex && !got_e && (*p == 'e' || *p == 'E'))
1676
              got_dot = got_e = 1;
1677
            /* This test does not include !hex, because a '.' always indicates
1678
               a decimal floating point number regardless of the radix.
1679
 
1680
               NOTE drow/2005-03-09: This comment is not accurate in C99;
1681
               however, it's not clear that all the floating point support
1682
               in this file is doing any good here.  */
1683
            else if (!got_dot && *p == '.')
1684
              got_dot = 1;
1685
            else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
1686
                     && (*p == '-' || *p == '+'))
1687
              /* This is the sign of the exponent, not the end of the
1688
                 number.  */
1689
              continue;
1690
            /* We will take any letters or digits.  parse_number will
1691
               complain if past the radix, or if L or U are not final.  */
1692
            else if (! ISALNUM (*p))
1693
              break;
1694
          }
1695
        toktype = parse_number (tokstart, p - tokstart, got_dot|got_e);
1696
        if (toktype == ERROR)
1697
          {
1698
            char *err_copy = (char *) alloca (p - tokstart + 1);
1699
 
1700
            memcpy (err_copy, tokstart, p - tokstart);
1701
            err_copy[p - tokstart] = 0;
1702
            yyerror ("invalid number");
1703
            return ERROR;
1704
          }
1705
        lexptr = p;
1706
        return toktype;
1707
      }
1708
 
1709
    case '+':
1710
      HANDLE_TOKEN2 ("+=", ASSIGN_MODIFY);
1711
      HANDLE_TOKEN2 ("++", INCREMENT);
1712
      lexptr++;
1713
      return c;
1714
    case '*':
1715
      HANDLE_TOKEN2 ("*=", ASSIGN_MODIFY);
1716
      lexptr++;
1717
      return c;
1718
    case '/':
1719
      HANDLE_TOKEN2 ("/=", ASSIGN_MODIFY);
1720
      lexptr++;
1721
      return c;
1722
    case '%':
1723
      HANDLE_TOKEN2 ("%=", ASSIGN_MODIFY);
1724
      lexptr++;
1725
      return c;
1726
    case '|':
1727
      HANDLE_TOKEN2 ("|=", ASSIGN_MODIFY);
1728
      HANDLE_TOKEN2 ("||", OROR);
1729
      lexptr++;
1730
      return c;
1731
    case '&':
1732
      HANDLE_TOKEN2 ("&=", ASSIGN_MODIFY);
1733
      HANDLE_TOKEN2 ("&&", ANDAND);
1734
      lexptr++;
1735
      return c;
1736
    case '^':
1737
      HANDLE_TOKEN2 ("^=", ASSIGN_MODIFY);
1738
      lexptr++;
1739
      return c;
1740
    case '!':
1741
      HANDLE_TOKEN2 ("!=", NOTEQUAL);
1742
      lexptr++;
1743
      return c;
1744
    case '<':
1745
      HANDLE_TOKEN3 ("<<=", ASSIGN_MODIFY);
1746
      HANDLE_TOKEN2 ("<=", LEQ);
1747
      HANDLE_TOKEN2 ("<<", LSH);
1748
      lexptr++;
1749
      return c;
1750
    case '>':
1751
      HANDLE_TOKEN3 (">>=", ASSIGN_MODIFY);
1752
      HANDLE_TOKEN2 (">=", GEQ);
1753
      HANDLE_TOKEN2 (">>", RSH);
1754
      lexptr++;
1755
      return c;
1756
    case '=':
1757
      HANDLE_TOKEN2 ("==", EQUAL);
1758
      lexptr++;
1759
      return c;
1760
    case ':':
1761
      HANDLE_TOKEN2 ("::", COLONCOLON);
1762
      lexptr++;
1763
      return c;
1764
 
1765
    case '[':
1766
    case ']':
1767
    case '?':
1768
    case '@':
1769
    case '~':
1770
    case '{':
1771
    case '}':
1772
    symbol:
1773
      lexptr++;
1774
      return c;
1775
 
1776
    case '"':
1777
      /* These can't occur in C++ names.  */
1778
      yyerror ("unexpected string literal");
1779
      return ERROR;
1780
    }
1781
 
1782
  if (!(c == '_' || c == '$' || ISALPHA (c)))
1783
    {
1784
      /* We must have come across a bad character (e.g. ';').  */
1785
      yyerror ("invalid character");
1786
      return ERROR;
1787
    }
1788
 
1789
  /* It's a name.  See how long it is.  */
1790
  namelen = 0;
1791
  do
1792
    c = tokstart[++namelen];
1793
  while (ISALNUM (c) || c == '_' || c == '$');
1794
 
1795
  lexptr += namelen;
1796
 
1797
  /* Catch specific keywords.  Notice that some of the keywords contain
1798
     spaces, and are sorted by the length of the first word.  They must
1799
     all include a trailing space in the string comparison.  */
1800
  switch (namelen)
1801
    {
1802
    case 16:
1803
      if (strncmp (tokstart, "reinterpret_cast", 16) == 0)
1804
        return REINTERPRET_CAST;
1805
      break;
1806
    case 12:
1807
      if (strncmp (tokstart, "construction vtable for ", 24) == 0)
1808
        {
1809
          lexptr = tokstart + 24;
1810
          return CONSTRUCTION_VTABLE;
1811
        }
1812
      if (strncmp (tokstart, "dynamic_cast", 12) == 0)
1813
        return DYNAMIC_CAST;
1814
      break;
1815
    case 11:
1816
      if (strncmp (tokstart, "static_cast", 11) == 0)
1817
        return STATIC_CAST;
1818
      break;
1819
    case 9:
1820
      HANDLE_SPECIAL ("covariant return thunk to ", DEMANGLE_COMPONENT_COVARIANT_THUNK);
1821
      HANDLE_SPECIAL ("reference temporary for ", DEMANGLE_COMPONENT_REFTEMP);
1822
      break;
1823
    case 8:
1824
      HANDLE_SPECIAL ("typeinfo for ", DEMANGLE_COMPONENT_TYPEINFO);
1825
      HANDLE_SPECIAL ("typeinfo fn for ", DEMANGLE_COMPONENT_TYPEINFO_FN);
1826
      HANDLE_SPECIAL ("typeinfo name for ", DEMANGLE_COMPONENT_TYPEINFO_NAME);
1827
      if (strncmp (tokstart, "operator", 8) == 0)
1828
        return OPERATOR;
1829
      if (strncmp (tokstart, "restrict", 8) == 0)
1830
        return RESTRICT;
1831
      if (strncmp (tokstart, "unsigned", 8) == 0)
1832
        return UNSIGNED;
1833
      if (strncmp (tokstart, "template", 8) == 0)
1834
        return TEMPLATE;
1835
      if (strncmp (tokstart, "volatile", 8) == 0)
1836
        return VOLATILE_KEYWORD;
1837
      break;
1838
    case 7:
1839
      HANDLE_SPECIAL ("virtual thunk to ", DEMANGLE_COMPONENT_VIRTUAL_THUNK);
1840
      if (strncmp (tokstart, "wchar_t", 7) == 0)
1841
        return WCHAR_T;
1842
      break;
1843
    case 6:
1844
      if (strncmp (tokstart, "global constructors keyed to ", 29) == 0)
1845
        {
1846
          const char *p;
1847
          lexptr = tokstart + 29;
1848
          yylval.lval = DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS;
1849
          /* Find the end of the symbol.  */
1850
          p = symbol_end (lexptr);
1851
          yylval.comp = make_name (lexptr, p - lexptr);
1852
          lexptr = p;
1853
          return DEMANGLER_SPECIAL;
1854
        }
1855
      if (strncmp (tokstart, "global destructors keyed to ", 28) == 0)
1856
        {
1857
          const char *p;
1858
          lexptr = tokstart + 28;
1859
          yylval.lval = DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS;
1860
          /* Find the end of the symbol.  */
1861
          p = symbol_end (lexptr);
1862
          yylval.comp = make_name (lexptr, p - lexptr);
1863
          lexptr = p;
1864
          return DEMANGLER_SPECIAL;
1865
        }
1866
 
1867
      HANDLE_SPECIAL ("vtable for ", DEMANGLE_COMPONENT_VTABLE);
1868
      if (strncmp (tokstart, "delete", 6) == 0)
1869
        return DELETE;
1870
      if (strncmp (tokstart, "struct", 6) == 0)
1871
        return STRUCT;
1872
      if (strncmp (tokstart, "signed", 6) == 0)
1873
        return SIGNED_KEYWORD;
1874
      if (strncmp (tokstart, "sizeof", 6) == 0)
1875
        return SIZEOF;
1876
      if (strncmp (tokstart, "double", 6) == 0)
1877
        return DOUBLE_KEYWORD;
1878
      break;
1879
    case 5:
1880
      HANDLE_SPECIAL ("guard variable for ", DEMANGLE_COMPONENT_GUARD);
1881
      if (strncmp (tokstart, "false", 5) == 0)
1882
        return FALSEKEYWORD;
1883
      if (strncmp (tokstart, "class", 5) == 0)
1884
        return CLASS;
1885
      if (strncmp (tokstart, "union", 5) == 0)
1886
        return UNION;
1887
      if (strncmp (tokstart, "float", 5) == 0)
1888
        return FLOAT_KEYWORD;
1889
      if (strncmp (tokstart, "short", 5) == 0)
1890
        return SHORT;
1891
      if (strncmp (tokstart, "const", 5) == 0)
1892
        return CONST_KEYWORD;
1893
      break;
1894
    case 4:
1895
      if (strncmp (tokstart, "void", 4) == 0)
1896
        return VOID;
1897
      if (strncmp (tokstart, "bool", 4) == 0)
1898
        return BOOL;
1899
      if (strncmp (tokstart, "char", 4) == 0)
1900
        return CHAR;
1901
      if (strncmp (tokstart, "enum", 4) == 0)
1902
        return ENUM;
1903
      if (strncmp (tokstart, "long", 4) == 0)
1904
        return LONG;
1905
      if (strncmp (tokstart, "true", 4) == 0)
1906
        return TRUEKEYWORD;
1907
      break;
1908
    case 3:
1909
      HANDLE_SPECIAL ("VTT for ", DEMANGLE_COMPONENT_VTT);
1910
      HANDLE_SPECIAL ("non-virtual thunk to ", DEMANGLE_COMPONENT_THUNK);
1911
      if (strncmp (tokstart, "new", 3) == 0)
1912
        return NEW;
1913
      if (strncmp (tokstart, "int", 3) == 0)
1914
        return INT_KEYWORD;
1915
      break;
1916
    default:
1917
      break;
1918
    }
1919
 
1920
  yylval.comp = make_name (tokstart, namelen);
1921
  return NAME;
1922
}
1923
 
1924
static void
1925
yyerror (char *msg)
1926
{
1927
  if (global_errmsg)
1928
    return;
1929
 
1930
  error_lexptr = prev_lexptr;
1931
  global_errmsg = msg ? msg : "parse error";
1932
}
1933
 
1934
/* Allocate a chunk of the components we'll need to build a tree.  We
1935
   generally allocate too many components, but the extra memory usage
1936
   doesn't hurt because the trees are temporary and the storage is
1937
   reused.  More may be allocated later, by d_grab.  */
1938
static void
1939
allocate_info (void)
1940
{
1941
  if (demangle_info == NULL)
1942
    {
1943
      demangle_info = malloc (sizeof (struct demangle_info));
1944
      demangle_info->prev = NULL;
1945
      demangle_info->next = NULL;
1946
    }
1947
  else
1948
    while (demangle_info->prev)
1949
      demangle_info = demangle_info->prev;
1950
 
1951
  demangle_info->used = 0;
1952
}
1953
 
1954
/* Convert RESULT to a string.  The return value is allocated
1955
   using xmalloc.  ESTIMATED_LEN is used only as a guide to the
1956
   length of the result.  This functions handles a few cases that
1957
   cplus_demangle_print does not, specifically the global destructor
1958
   and constructor labels.  */
1959
 
1960
char *
1961
cp_comp_to_string (struct demangle_component *result, int estimated_len)
1962
{
1963
  size_t err;
1964
 
1965
  return cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, result, estimated_len,
1966
                               &err);
1967
}
1968
 
1969
/* Convert a demangled name to a demangle_component tree.  On success,
1970
   the root of the new tree is returned; it is valid until the next
1971
   call to this function and should not be freed.  On error, NULL is
1972
   returned, and an error message will be set in *ERRMSG (which does
1973
   not need to be freed).  */
1974
 
1975
struct demangle_component *
1976
cp_demangled_name_to_comp (const char *demangled_name, const char **errmsg)
1977
{
1978
  static char errbuf[60];
1979
  struct demangle_component *result;
1980
 
1981
  prev_lexptr = lexptr = demangled_name;
1982
  error_lexptr = NULL;
1983
  global_errmsg = NULL;
1984
 
1985
  allocate_info ();
1986
 
1987
  if (yyparse ())
1988
    {
1989
      if (global_errmsg && errmsg)
1990
        {
1991
          snprintf (errbuf, sizeof (errbuf) - 2, "%s, near `%s",
1992
                    global_errmsg, error_lexptr);
1993
          strcat (errbuf, "'");
1994
          *errmsg = errbuf;
1995
        }
1996
      return NULL;
1997
    }
1998
 
1999
  result = global_result;
2000
  global_result = NULL;
2001
 
2002
  return result;
2003
}
2004
 
2005
#ifdef TEST_CPNAMES
2006
 
2007
static void
2008
cp_print (struct demangle_component *result)
2009
{
2010
  char *str;
2011
  size_t err = 0;
2012
 
2013
  str = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, result, 64, &err);
2014
  if (str == NULL)
2015
    return;
2016
 
2017
  fputs (str, stdout);
2018
 
2019
  free (str);
2020
}
2021
 
2022
static char
2023
trim_chars (char *lexptr, char **extra_chars)
2024
{
2025
  char *p = (char *) symbol_end (lexptr);
2026
  char c = 0;
2027
 
2028
  if (*p)
2029
    {
2030
      c = *p;
2031
      *p = 0;
2032
      *extra_chars = p + 1;
2033
    }
2034
 
2035
  return c;
2036
}
2037
 
2038
/* When this file is built as a standalone program, xmalloc comes from
2039
   libiberty --- in which case we have to provide xfree ourselves.  */
2040
 
2041
void
2042
xfree (void *ptr)
2043
{
2044
  if (ptr != NULL)
2045
    free (ptr);
2046
}
2047
 
2048
int
2049
main (int argc, char **argv)
2050
{
2051
  char *str2, *extra_chars = "", c;
2052
  char buf[65536];
2053
  int arg;
2054
  const char *errmsg;
2055
  struct demangle_component *result;
2056
 
2057
  arg = 1;
2058
  if (argv[arg] && strcmp (argv[arg], "--debug") == 0)
2059
    {
2060
      yydebug = 1;
2061
      arg++;
2062
    }
2063
 
2064
  if (argv[arg] == NULL)
2065
    while (fgets (buf, 65536, stdin) != NULL)
2066
      {
2067
        int len;
2068
        buf[strlen (buf) - 1] = 0;
2069
        /* Use DMGL_VERBOSE to get expanded standard substitutions.  */
2070
        c = trim_chars (buf, &extra_chars);
2071
        str2 = cplus_demangle (buf, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
2072
        if (str2 == NULL)
2073
          {
2074
            /* printf ("Demangling error\n"); */
2075
            if (c)
2076
              printf ("%s%c%s\n", buf, c, extra_chars);
2077
            else
2078
              printf ("%s\n", buf);
2079
            continue;
2080
          }
2081
        result = cp_demangled_name_to_comp (str2, &errmsg);
2082
        if (result == NULL)
2083
          {
2084
            fputs (errmsg, stderr);
2085
            fputc ('\n', stderr);
2086
            continue;
2087
          }
2088
 
2089
        cp_print (result);
2090
 
2091
        free (str2);
2092
        if (c)
2093
          {
2094
            putchar (c);
2095
            fputs (extra_chars, stdout);
2096
          }
2097
        putchar ('\n');
2098
      }
2099
  else
2100
    {
2101
      result = cp_demangled_name_to_comp (argv[arg], &errmsg);
2102
      if (result == NULL)
2103
        {
2104
          fputs (errmsg, stderr);
2105
          fputc ('\n', stderr);
2106
          return 0;
2107
        }
2108
      cp_print (result);
2109
      putchar ('\n');
2110
    }
2111
  return 0;
2112
}
2113
 
2114
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.