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