xref: /netbsd-src/external/gpl3/binutils.old/dist/libiberty/cp-demint.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
116dce513Schristos /* Demangler component interface functions.
2*e992f068Schristos    Copyright (C) 2004-2022 Free Software Foundation, Inc.
316dce513Schristos    Written by Ian Lance Taylor <ian@wasabisystems.com>.
416dce513Schristos 
516dce513Schristos    This file is part of the libiberty library, which is part of GCC.
616dce513Schristos 
716dce513Schristos    This file is free software; you can redistribute it and/or modify
816dce513Schristos    it under the terms of the GNU General Public License as published by
916dce513Schristos    the Free Software Foundation; either version 2 of the License, or
1016dce513Schristos    (at your option) any later version.
1116dce513Schristos 
1216dce513Schristos    In addition to the permissions in the GNU General Public License, the
1316dce513Schristos    Free Software Foundation gives you unlimited permission to link the
1416dce513Schristos    compiled version of this file into combinations with other programs,
1516dce513Schristos    and to distribute those combinations without any restriction coming
1616dce513Schristos    from the use of this file.  (The General Public License restrictions
1716dce513Schristos    do apply in other respects; for example, they cover modification of
1816dce513Schristos    the file, and distribution when not linked into a combined
1916dce513Schristos    executable.)
2016dce513Schristos 
2116dce513Schristos    This program is distributed in the hope that it will be useful,
2216dce513Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
2316dce513Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2416dce513Schristos    GNU General Public License for more details.
2516dce513Schristos 
2616dce513Schristos    You should have received a copy of the GNU General Public License
2716dce513Schristos    along with this program; if not, write to the Free Software
2816dce513Schristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
2916dce513Schristos */
3016dce513Schristos 
3116dce513Schristos /* This file implements a few interface functions which are provided
3216dce513Schristos    for use with struct demangle_component trees.  These functions are
3316dce513Schristos    declared in demangle.h.  These functions are closely tied to the
3416dce513Schristos    demangler code in cp-demangle.c, and other interface functions can
3516dce513Schristos    be found in that file.  We put these functions in a separate file
3616dce513Schristos    because they are not needed by the demangler, and so we avoid
3716dce513Schristos    having them pulled in by programs which only need the
3816dce513Schristos    demangler.  */
3916dce513Schristos 
4016dce513Schristos #ifdef HAVE_CONFIG_H
4116dce513Schristos #include "config.h"
4216dce513Schristos #endif
4316dce513Schristos 
4416dce513Schristos #ifdef HAVE_STDLIB_H
4516dce513Schristos #include <stdlib.h>
4616dce513Schristos #endif
4716dce513Schristos #ifdef HAVE_STRING_H
4816dce513Schristos #include <string.h>
4916dce513Schristos #endif
5016dce513Schristos 
5116dce513Schristos #include "ansidecl.h"
5216dce513Schristos #include "libiberty.h"
5316dce513Schristos #include "demangle.h"
5416dce513Schristos #include "cp-demangle.h"
5516dce513Schristos 
5616dce513Schristos /* Fill in most component types.  */
5716dce513Schristos 
5816dce513Schristos int
cplus_demangle_fill_component(struct demangle_component * p,enum demangle_component_type type,struct demangle_component * left,struct demangle_component * right)5916dce513Schristos cplus_demangle_fill_component (struct demangle_component *p,
6016dce513Schristos                                enum demangle_component_type type,
6116dce513Schristos                                struct demangle_component *left,
6216dce513Schristos                                 struct demangle_component *right)
6316dce513Schristos {
6416dce513Schristos   if (p == NULL)
6516dce513Schristos     return 0;
6616dce513Schristos   switch (type)
6716dce513Schristos     {
6816dce513Schristos     case DEMANGLE_COMPONENT_QUAL_NAME:
6916dce513Schristos     case DEMANGLE_COMPONENT_LOCAL_NAME:
7016dce513Schristos     case DEMANGLE_COMPONENT_TYPED_NAME:
7116dce513Schristos     case DEMANGLE_COMPONENT_TEMPLATE:
7216dce513Schristos     case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
7316dce513Schristos     case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
7416dce513Schristos     case DEMANGLE_COMPONENT_FUNCTION_TYPE:
7516dce513Schristos     case DEMANGLE_COMPONENT_ARRAY_TYPE:
7616dce513Schristos     case DEMANGLE_COMPONENT_PTRMEM_TYPE:
7716dce513Schristos     case DEMANGLE_COMPONENT_ARGLIST:
7816dce513Schristos     case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
7916dce513Schristos     case DEMANGLE_COMPONENT_UNARY:
8016dce513Schristos     case DEMANGLE_COMPONENT_BINARY:
8116dce513Schristos     case DEMANGLE_COMPONENT_BINARY_ARGS:
8216dce513Schristos     case DEMANGLE_COMPONENT_TRINARY:
8316dce513Schristos     case DEMANGLE_COMPONENT_TRINARY_ARG1:
8416dce513Schristos     case DEMANGLE_COMPONENT_TRINARY_ARG2:
8516dce513Schristos     case DEMANGLE_COMPONENT_LITERAL:
8616dce513Schristos     case DEMANGLE_COMPONENT_LITERAL_NEG:
8716dce513Schristos       break;
8816dce513Schristos 
8916dce513Schristos       /* These component types only have one subtree.  */
9016dce513Schristos     case DEMANGLE_COMPONENT_VTABLE:
9116dce513Schristos     case DEMANGLE_COMPONENT_VTT:
9216dce513Schristos     case DEMANGLE_COMPONENT_TYPEINFO:
9316dce513Schristos     case DEMANGLE_COMPONENT_TYPEINFO_NAME:
9416dce513Schristos     case DEMANGLE_COMPONENT_TYPEINFO_FN:
9516dce513Schristos     case DEMANGLE_COMPONENT_THUNK:
9616dce513Schristos     case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
9716dce513Schristos     case DEMANGLE_COMPONENT_COVARIANT_THUNK:
9816dce513Schristos     case DEMANGLE_COMPONENT_JAVA_CLASS:
9916dce513Schristos     case DEMANGLE_COMPONENT_GUARD:
10016dce513Schristos     case DEMANGLE_COMPONENT_REFTEMP:
10116dce513Schristos     case DEMANGLE_COMPONENT_RESTRICT:
10216dce513Schristos     case DEMANGLE_COMPONENT_VOLATILE:
10316dce513Schristos     case DEMANGLE_COMPONENT_CONST:
10416dce513Schristos     case DEMANGLE_COMPONENT_RESTRICT_THIS:
10516dce513Schristos     case DEMANGLE_COMPONENT_VOLATILE_THIS:
10616dce513Schristos     case DEMANGLE_COMPONENT_CONST_THIS:
10716dce513Schristos     case DEMANGLE_COMPONENT_POINTER:
10816dce513Schristos     case DEMANGLE_COMPONENT_REFERENCE:
109ede78133Schristos     case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
11016dce513Schristos     case DEMANGLE_COMPONENT_COMPLEX:
11116dce513Schristos     case DEMANGLE_COMPONENT_IMAGINARY:
11216dce513Schristos     case DEMANGLE_COMPONENT_VENDOR_TYPE:
11316dce513Schristos     case DEMANGLE_COMPONENT_CAST:
11416dce513Schristos     case DEMANGLE_COMPONENT_CONVERSION:
11516dce513Schristos       if (right != NULL)
11616dce513Schristos 	return 0;
11716dce513Schristos       break;
11816dce513Schristos 
11916dce513Schristos     default:
12016dce513Schristos       /* Other types do not use subtrees.  */
12116dce513Schristos       return 0;
12216dce513Schristos     }
12316dce513Schristos 
12416dce513Schristos   p->type = type;
12516dce513Schristos   p->u.s_binary.left = left;
12616dce513Schristos   p->u.s_binary.right = right;
127ede78133Schristos   p->d_printing = 0;
128012573ebSchristos   p->d_counting = 0;
12916dce513Schristos 
13016dce513Schristos   return 1;
13116dce513Schristos }
13216dce513Schristos 
13316dce513Schristos /* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE.  */
13416dce513Schristos 
13516dce513Schristos int
cplus_demangle_fill_builtin_type(struct demangle_component * p,const char * type_name)13616dce513Schristos cplus_demangle_fill_builtin_type (struct demangle_component *p,
13716dce513Schristos                                   const char *type_name)
13816dce513Schristos {
13916dce513Schristos   int len;
14016dce513Schristos   unsigned int i;
14116dce513Schristos 
14216dce513Schristos   if (p == NULL || type_name == NULL)
14316dce513Schristos     return 0;
14416dce513Schristos   len = strlen (type_name);
14516dce513Schristos   for (i = 0; i < D_BUILTIN_TYPE_COUNT; ++i)
14616dce513Schristos     {
14716dce513Schristos       if (len == cplus_demangle_builtin_types[i].len
14816dce513Schristos 	  && strcmp (type_name, cplus_demangle_builtin_types[i].name) == 0)
14916dce513Schristos 	{
15016dce513Schristos 	  p->type = DEMANGLE_COMPONENT_BUILTIN_TYPE;
15116dce513Schristos 	  p->u.s_builtin.type = &cplus_demangle_builtin_types[i];
152ede78133Schristos 	  p->d_printing = 0;
153012573ebSchristos 	  p->d_counting = 0;
15416dce513Schristos 	  return 1;
15516dce513Schristos 	}
15616dce513Schristos     }
15716dce513Schristos   return 0;
15816dce513Schristos }
15916dce513Schristos 
16016dce513Schristos /* Fill in a DEMANGLE_COMPONENT_OPERATOR.  */
16116dce513Schristos 
16216dce513Schristos int
cplus_demangle_fill_operator(struct demangle_component * p,const char * opname,int args)16316dce513Schristos cplus_demangle_fill_operator (struct demangle_component *p,
16416dce513Schristos                               const char *opname, int args)
16516dce513Schristos {
16616dce513Schristos   int len;
16716dce513Schristos   unsigned int i;
16816dce513Schristos 
16916dce513Schristos   if (p == NULL || opname == NULL)
17016dce513Schristos     return 0;
17116dce513Schristos   len = strlen (opname);
17216dce513Schristos   for (i = 0; cplus_demangle_operators[i].name != NULL; ++i)
17316dce513Schristos     {
17416dce513Schristos       if (len == cplus_demangle_operators[i].len
17516dce513Schristos 	  && args == cplus_demangle_operators[i].args
17616dce513Schristos 	  && strcmp (opname, cplus_demangle_operators[i].name) == 0)
17716dce513Schristos 	{
17816dce513Schristos 	  p->type = DEMANGLE_COMPONENT_OPERATOR;
17916dce513Schristos 	  p->u.s_operator.op = &cplus_demangle_operators[i];
180ede78133Schristos 	  p->d_printing = 0;
181012573ebSchristos 	  p->d_counting = 0;
18216dce513Schristos 	  return 1;
18316dce513Schristos 	}
18416dce513Schristos     }
18516dce513Schristos   return 0;
18616dce513Schristos }
18716dce513Schristos 
18816dce513Schristos /* Translate a mangled name into components.  */
18916dce513Schristos 
19016dce513Schristos struct demangle_component *
cplus_demangle_v3_components(const char * mangled,int options,void ** mem)19116dce513Schristos cplus_demangle_v3_components (const char *mangled, int options, void **mem)
19216dce513Schristos {
19316dce513Schristos   size_t len;
19416dce513Schristos   int type;
19516dce513Schristos   struct d_info di;
19616dce513Schristos   struct demangle_component *dc;
19716dce513Schristos 
19816dce513Schristos   len = strlen (mangled);
19916dce513Schristos 
20016dce513Schristos   if (mangled[0] == '_' && mangled[1] == 'Z')
20116dce513Schristos     type = 0;
20216dce513Schristos   else
20316dce513Schristos     {
20416dce513Schristos       if ((options & DMGL_TYPES) == 0)
20516dce513Schristos 	return NULL;
20616dce513Schristos       type = 1;
20716dce513Schristos     }
20816dce513Schristos 
20916dce513Schristos   cplus_demangle_init_info (mangled, options, len, &di);
21016dce513Schristos 
21116dce513Schristos   di.comps = ((struct demangle_component *)
21216dce513Schristos 	      malloc (di.num_comps * sizeof (struct demangle_component)));
21316dce513Schristos   di.subs = ((struct demangle_component **)
21416dce513Schristos 	     malloc (di.num_subs * sizeof (struct demangle_component *)));
21516dce513Schristos   if (di.comps == NULL || di.subs == NULL)
21616dce513Schristos     {
21716dce513Schristos       free (di.comps);
21816dce513Schristos       free (di.subs);
21916dce513Schristos       return NULL;
22016dce513Schristos     }
22116dce513Schristos 
22216dce513Schristos   if (! type)
22316dce513Schristos     dc = cplus_demangle_mangled_name (&di, 1);
22416dce513Schristos   else
22516dce513Schristos     dc = cplus_demangle_type (&di);
22616dce513Schristos 
22716dce513Schristos   /* If DMGL_PARAMS is set, then if we didn't consume the entire
22816dce513Schristos      mangled string, then we didn't successfully demangle it.  */
22916dce513Schristos   if ((options & DMGL_PARAMS) != 0 && d_peek_char (&di) != '\0')
23016dce513Schristos     dc = NULL;
23116dce513Schristos 
23216dce513Schristos   free (di.subs);
23316dce513Schristos 
23416dce513Schristos   if (dc != NULL)
23516dce513Schristos     *mem = di.comps;
23616dce513Schristos   else
23716dce513Schristos     free (di.comps);
23816dce513Schristos 
23916dce513Schristos   return dc;
24016dce513Schristos }
241