1130561Sobrien/* Demangler component interface functions.
2130561Sobrien   Copyright (C) 2004 Free Software Foundation, Inc.
3130561Sobrien   Written by Ian Lance Taylor <ian@wasabisystems.com>.
4130561Sobrien
5130561Sobrien   This file is part of the libiberty library, which is part of GCC.
6130561Sobrien
7130561Sobrien   This file is free software; you can redistribute it and/or modify
8130561Sobrien   it under the terms of the GNU General Public License as published by
9130561Sobrien   the Free Software Foundation; either version 2 of the License, or
10130561Sobrien   (at your option) any later version.
11130561Sobrien
12130561Sobrien   In addition to the permissions in the GNU General Public License, the
13130561Sobrien   Free Software Foundation gives you unlimited permission to link the
14130561Sobrien   compiled version of this file into combinations with other programs,
15130561Sobrien   and to distribute those combinations without any restriction coming
16130561Sobrien   from the use of this file.  (The General Public License restrictions
17130561Sobrien   do apply in other respects; for example, they cover modification of
18130561Sobrien   the file, and distribution when not linked into a combined
19130561Sobrien   executable.)
20130561Sobrien
21130561Sobrien   This program is distributed in the hope that it will be useful,
22130561Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
23130561Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24130561Sobrien   GNU General Public License for more details.
25130561Sobrien
26130561Sobrien   You should have received a copy of the GNU General Public License
27130561Sobrien   along with this program; if not, write to the Free Software
28218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
29130561Sobrien*/
30130561Sobrien
31130561Sobrien/* This file implements a few interface functions which are provided
32130561Sobrien   for use with struct demangle_component trees.  These functions are
33130561Sobrien   declared in demangle.h.  These functions are closely tied to the
34130561Sobrien   demangler code in cp-demangle.c, and other interface functions can
35130561Sobrien   be found in that file.  We put these functions in a separate file
36130561Sobrien   because they are not needed by the demangler, and so we avoid
37130561Sobrien   having them pulled in by programs which only need the
38130561Sobrien   demangler.  */
39130561Sobrien
40130561Sobrien#ifdef HAVE_CONFIG_H
41130561Sobrien#include "config.h"
42130561Sobrien#endif
43130561Sobrien
44130561Sobrien#ifdef HAVE_STDLIB_H
45130561Sobrien#include <stdlib.h>
46130561Sobrien#endif
47130561Sobrien#ifdef HAVE_STRING_H
48130561Sobrien#include <string.h>
49130561Sobrien#endif
50130561Sobrien
51130561Sobrien#include "ansidecl.h"
52130561Sobrien#include "libiberty.h"
53130561Sobrien#include "demangle.h"
54130561Sobrien#include "cp-demangle.h"
55130561Sobrien
56130561Sobrien/* Fill in most component types.  */
57130561Sobrien
58130561Sobrienint
59218822Sdimcplus_demangle_fill_component (struct demangle_component *p,
60218822Sdim                               enum demangle_component_type type,
61218822Sdim                               struct demangle_component *left,
62218822Sdim                                struct demangle_component *right)
63130561Sobrien{
64130561Sobrien  if (p == NULL)
65130561Sobrien    return 0;
66130561Sobrien  switch (type)
67130561Sobrien    {
68130561Sobrien    case DEMANGLE_COMPONENT_QUAL_NAME:
69130561Sobrien    case DEMANGLE_COMPONENT_LOCAL_NAME:
70130561Sobrien    case DEMANGLE_COMPONENT_TYPED_NAME:
71130561Sobrien    case DEMANGLE_COMPONENT_TEMPLATE:
72130561Sobrien    case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
73130561Sobrien    case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
74130561Sobrien    case DEMANGLE_COMPONENT_FUNCTION_TYPE:
75130561Sobrien    case DEMANGLE_COMPONENT_ARRAY_TYPE:
76130561Sobrien    case DEMANGLE_COMPONENT_PTRMEM_TYPE:
77130561Sobrien    case DEMANGLE_COMPONENT_ARGLIST:
78130561Sobrien    case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
79130561Sobrien    case DEMANGLE_COMPONENT_UNARY:
80130561Sobrien    case DEMANGLE_COMPONENT_BINARY:
81130561Sobrien    case DEMANGLE_COMPONENT_BINARY_ARGS:
82130561Sobrien    case DEMANGLE_COMPONENT_TRINARY:
83130561Sobrien    case DEMANGLE_COMPONENT_TRINARY_ARG1:
84130561Sobrien    case DEMANGLE_COMPONENT_TRINARY_ARG2:
85130561Sobrien    case DEMANGLE_COMPONENT_LITERAL:
86130561Sobrien    case DEMANGLE_COMPONENT_LITERAL_NEG:
87130561Sobrien      break;
88130561Sobrien
89130561Sobrien      /* These component types only have one subtree.  */
90130561Sobrien    case DEMANGLE_COMPONENT_VTABLE:
91130561Sobrien    case DEMANGLE_COMPONENT_VTT:
92130561Sobrien    case DEMANGLE_COMPONENT_TYPEINFO:
93130561Sobrien    case DEMANGLE_COMPONENT_TYPEINFO_NAME:
94130561Sobrien    case DEMANGLE_COMPONENT_TYPEINFO_FN:
95130561Sobrien    case DEMANGLE_COMPONENT_THUNK:
96130561Sobrien    case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
97130561Sobrien    case DEMANGLE_COMPONENT_COVARIANT_THUNK:
98130561Sobrien    case DEMANGLE_COMPONENT_JAVA_CLASS:
99130561Sobrien    case DEMANGLE_COMPONENT_GUARD:
100130561Sobrien    case DEMANGLE_COMPONENT_REFTEMP:
101130561Sobrien    case DEMANGLE_COMPONENT_RESTRICT:
102130561Sobrien    case DEMANGLE_COMPONENT_VOLATILE:
103130561Sobrien    case DEMANGLE_COMPONENT_CONST:
104130561Sobrien    case DEMANGLE_COMPONENT_RESTRICT_THIS:
105130561Sobrien    case DEMANGLE_COMPONENT_VOLATILE_THIS:
106130561Sobrien    case DEMANGLE_COMPONENT_CONST_THIS:
107130561Sobrien    case DEMANGLE_COMPONENT_POINTER:
108130561Sobrien    case DEMANGLE_COMPONENT_REFERENCE:
109130561Sobrien    case DEMANGLE_COMPONENT_COMPLEX:
110130561Sobrien    case DEMANGLE_COMPONENT_IMAGINARY:
111130561Sobrien    case DEMANGLE_COMPONENT_VENDOR_TYPE:
112130561Sobrien    case DEMANGLE_COMPONENT_CAST:
113130561Sobrien      if (right != NULL)
114130561Sobrien	return 0;
115130561Sobrien      break;
116130561Sobrien
117130561Sobrien    default:
118130561Sobrien      /* Other types do not use subtrees.  */
119130561Sobrien      return 0;
120130561Sobrien    }
121130561Sobrien
122130561Sobrien  p->type = type;
123130561Sobrien  p->u.s_binary.left = left;
124130561Sobrien  p->u.s_binary.right = right;
125130561Sobrien
126130561Sobrien  return 1;
127130561Sobrien}
128130561Sobrien
129130561Sobrien/* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE.  */
130130561Sobrien
131130561Sobrienint
132218822Sdimcplus_demangle_fill_builtin_type (struct demangle_component *p,
133218822Sdim                                  const char *type_name)
134130561Sobrien{
135130561Sobrien  int len;
136130561Sobrien  unsigned int i;
137130561Sobrien
138218822Sdim  if (p == NULL || type_name == NULL)
139130561Sobrien    return 0;
140218822Sdim  len = strlen (type_name);
141130561Sobrien  for (i = 0; i < D_BUILTIN_TYPE_COUNT; ++i)
142130561Sobrien    {
143130561Sobrien      if (len == cplus_demangle_builtin_types[i].len
144218822Sdim	  && strcmp (type_name, cplus_demangle_builtin_types[i].name) == 0)
145130561Sobrien	{
146130561Sobrien	  p->type = DEMANGLE_COMPONENT_BUILTIN_TYPE;
147130561Sobrien	  p->u.s_builtin.type = &cplus_demangle_builtin_types[i];
148130561Sobrien	  return 1;
149130561Sobrien	}
150130561Sobrien    }
151130561Sobrien  return 0;
152130561Sobrien}
153130561Sobrien
154130561Sobrien/* Fill in a DEMANGLE_COMPONENT_OPERATOR.  */
155130561Sobrien
156130561Sobrienint
157218822Sdimcplus_demangle_fill_operator (struct demangle_component *p,
158218822Sdim                              const char *opname, int args)
159130561Sobrien{
160130561Sobrien  int len;
161130561Sobrien  unsigned int i;
162130561Sobrien
163130561Sobrien  if (p == NULL || opname == NULL)
164130561Sobrien    return 0;
165130561Sobrien  len = strlen (opname);
166130561Sobrien  for (i = 0; cplus_demangle_operators[i].name != NULL; ++i)
167130561Sobrien    {
168130561Sobrien      if (len == cplus_demangle_operators[i].len
169130561Sobrien	  && args == cplus_demangle_operators[i].args
170130561Sobrien	  && strcmp (opname, cplus_demangle_operators[i].name) == 0)
171130561Sobrien	{
172130561Sobrien	  p->type = DEMANGLE_COMPONENT_OPERATOR;
173130561Sobrien	  p->u.s_operator.op = &cplus_demangle_operators[i];
174130561Sobrien	  return 1;
175130561Sobrien	}
176130561Sobrien    }
177130561Sobrien  return 0;
178130561Sobrien}
179130561Sobrien
180130561Sobrien/* Translate a mangled name into components.  */
181130561Sobrien
182130561Sobrienstruct demangle_component *
183218822Sdimcplus_demangle_v3_components (const char *mangled, int options, void **mem)
184130561Sobrien{
185130561Sobrien  size_t len;
186130561Sobrien  int type;
187130561Sobrien  struct d_info di;
188130561Sobrien  struct demangle_component *dc;
189130561Sobrien
190130561Sobrien  len = strlen (mangled);
191130561Sobrien
192130561Sobrien  if (mangled[0] == '_' && mangled[1] == 'Z')
193130561Sobrien    type = 0;
194130561Sobrien  else
195130561Sobrien    {
196130561Sobrien      if ((options & DMGL_TYPES) == 0)
197130561Sobrien	return NULL;
198130561Sobrien      type = 1;
199130561Sobrien    }
200130561Sobrien
201130561Sobrien  cplus_demangle_init_info (mangled, options, len, &di);
202130561Sobrien
203130561Sobrien  di.comps = ((struct demangle_component *)
204130561Sobrien	      malloc (di.num_comps * sizeof (struct demangle_component)));
205130561Sobrien  di.subs = ((struct demangle_component **)
206130561Sobrien	     malloc (di.num_subs * sizeof (struct demangle_component *)));
207130561Sobrien  if (di.comps == NULL || di.subs == NULL)
208130561Sobrien    {
209130561Sobrien      if (di.comps != NULL)
210130561Sobrien	free (di.comps);
211130561Sobrien      if (di.subs != NULL)
212130561Sobrien	free (di.subs);
213130561Sobrien      return NULL;
214130561Sobrien    }
215130561Sobrien
216130561Sobrien  if (! type)
217130561Sobrien    dc = cplus_demangle_mangled_name (&di, 1);
218130561Sobrien  else
219130561Sobrien    dc = cplus_demangle_type (&di);
220130561Sobrien
221130561Sobrien  /* If DMGL_PARAMS is set, then if we didn't consume the entire
222130561Sobrien     mangled string, then we didn't successfully demangle it.  */
223130561Sobrien  if ((options & DMGL_PARAMS) != 0 && d_peek_char (&di) != '\0')
224130561Sobrien    dc = NULL;
225130561Sobrien
226130561Sobrien  free (di.subs);
227130561Sobrien
228130561Sobrien  if (dc != NULL)
229130561Sobrien    *mem = di.comps;
230130561Sobrien  else
231130561Sobrien    free (di.comps);
232130561Sobrien
233130561Sobrien  return dc;
234130561Sobrien}
235