/* Demangler component interface functions.
   Copyright (C) 2004-2018 Free Software Foundation, Inc.
   Written by Ian Lance Taylor <ian@wasabisystems.com>.

   This file is part of the libiberty library, which is part of GCC.

   This file is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   In addition to the permissions in the GNU General Public License, the
   Free Software Foundation gives you unlimited permission to link the
   compiled version of this file into combinations with other programs,
   and to distribute those combinations without any restriction coming
   from the use of this file.  (The General Public License restrictions
   do apply in other respects; for example, they cover modification of
   the file, and distribution when not linked into a combined
   executable.)

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 
*/

/* This file implements a few interface functions which are provided
   for use with struct demangle_component trees.  These functions are
   declared in demangle.h.  These functions are closely tied to the
   demangler code in cp-demangle.c, and other interface functions can
   be found in that file.  We put these functions in a separate file
   because they are not needed by the demangler, and so we avoid
   having them pulled in by programs which only need the
   demangler.  */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif

#include "ansidecl.h"
#include "libiberty.h"
#include "demangle.h"
#include "cp-demangle.h"

/* Fill in most component types.  */

int
cplus_demangle_fill_component (struct demangle_component *p,
                               enum demangle_component_type type,
                               struct demangle_component *left,
                                struct demangle_component *right)
{
  if (p == NULL)
    return 0;
  switch (type)
    {
    case DEMANGLE_COMPONENT_QUAL_NAME:
    case DEMANGLE_COMPONENT_LOCAL_NAME:
    case DEMANGLE_COMPONENT_TYPED_NAME:
    case DEMANGLE_COMPONENT_TEMPLATE:
    case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
    case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
    case DEMANGLE_COMPONENT_FUNCTION_TYPE:
    case DEMANGLE_COMPONENT_ARRAY_TYPE:
    case DEMANGLE_COMPONENT_PTRMEM_TYPE:
    case DEMANGLE_COMPONENT_ARGLIST:
    case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
    case DEMANGLE_COMPONENT_UNARY:
    case DEMANGLE_COMPONENT_BINARY:
    case DEMANGLE_COMPONENT_BINARY_ARGS:
    case DEMANGLE_COMPONENT_TRINARY:
    case DEMANGLE_COMPONENT_TRINARY_ARG1:
    case DEMANGLE_COMPONENT_TRINARY_ARG2:
    case DEMANGLE_COMPONENT_LITERAL:
    case DEMANGLE_COMPONENT_LITERAL_NEG:
      break;

      /* These component types only have one subtree.  */
    case DEMANGLE_COMPONENT_VTABLE:
    case DEMANGLE_COMPONENT_VTT:
    case DEMANGLE_COMPONENT_TYPEINFO:
    case DEMANGLE_COMPONENT_TYPEINFO_NAME:
    case DEMANGLE_COMPONENT_TYPEINFO_FN:
    case DEMANGLE_COMPONENT_THUNK:
    case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
    case DEMANGLE_COMPONENT_COVARIANT_THUNK:
    case DEMANGLE_COMPONENT_JAVA_CLASS:
    case DEMANGLE_COMPONENT_GUARD:
    case DEMANGLE_COMPONENT_REFTEMP:
    case DEMANGLE_COMPONENT_RESTRICT:
    case DEMANGLE_COMPONENT_VOLATILE:
    case DEMANGLE_COMPONENT_CONST:
    case DEMANGLE_COMPONENT_RESTRICT_THIS:
    case DEMANGLE_COMPONENT_VOLATILE_THIS:
    case DEMANGLE_COMPONENT_CONST_THIS:
    case DEMANGLE_COMPONENT_POINTER:
    case DEMANGLE_COMPONENT_REFERENCE:
    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
    case DEMANGLE_COMPONENT_COMPLEX:
    case DEMANGLE_COMPONENT_IMAGINARY:
    case DEMANGLE_COMPONENT_VENDOR_TYPE:
    case DEMANGLE_COMPONENT_CAST:
    case DEMANGLE_COMPONENT_CONVERSION:
      if (right != NULL)
	return 0;
      break;

    default:
      /* Other types do not use subtrees.  */
      return 0;
    }

  p->type = type;
  p->u.s_binary.left = left;
  p->u.s_binary.right = right;
  p->d_printing = 0;

  return 1;
}

/* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE.  */

int
cplus_demangle_fill_builtin_type (struct demangle_component *p,
                                  const char *type_name)
{
  int len;
  unsigned int i;

  if (p == NULL || type_name == NULL)
    return 0;
  len = strlen (type_name);
  for (i = 0; i < D_BUILTIN_TYPE_COUNT; ++i)
    {
      if (len == cplus_demangle_builtin_types[i].len
	  && strcmp (type_name, cplus_demangle_builtin_types[i].name) == 0)
	{
	  p->type = DEMANGLE_COMPONENT_BUILTIN_TYPE;
	  p->u.s_builtin.type = &cplus_demangle_builtin_types[i];
	  p->d_printing = 0;
	  return 1;
	}
    }
  return 0;
}

/* Fill in a DEMANGLE_COMPONENT_OPERATOR.  */

int
cplus_demangle_fill_operator (struct demangle_component *p,
                              const char *opname, int args)
{
  int len;
  unsigned int i;

  if (p == NULL || opname == NULL)
    return 0;
  len = strlen (opname);
  for (i = 0; cplus_demangle_operators[i].name != NULL; ++i)
    {
      if (len == cplus_demangle_operators[i].len
	  && args == cplus_demangle_operators[i].args
	  && strcmp (opname, cplus_demangle_operators[i].name) == 0)
	{
	  p->type = DEMANGLE_COMPONENT_OPERATOR;
	  p->u.s_operator.op = &cplus_demangle_operators[i];
	  p->d_printing = 0;
	  return 1;
	}
    }
  return 0;
}

/* Translate a mangled name into components.  */

struct demangle_component *
cplus_demangle_v3_components (const char *mangled, int options, void **mem)
{
  size_t len;
  int type;
  struct d_info di;
  struct demangle_component *dc;

  len = strlen (mangled);

  if (mangled[0] == '_' && mangled[1] == 'Z')
    type = 0;
  else
    {
      if ((options & DMGL_TYPES) == 0)
	return NULL;
      type = 1;
    }

  cplus_demangle_init_info (mangled, options, len, &di);

  di.comps = ((struct demangle_component *)
	      malloc (di.num_comps * sizeof (struct demangle_component)));
  di.subs = ((struct demangle_component **)
	     malloc (di.num_subs * sizeof (struct demangle_component *)));
  if (di.comps == NULL || di.subs == NULL)
    {
      free (di.comps);
      free (di.subs);
      return NULL;
    }

  if (! type)
    dc = cplus_demangle_mangled_name (&di, 1);
  else
    dc = cplus_demangle_type (&di);

  /* If DMGL_PARAMS is set, then if we didn't consume the entire
     mangled string, then we didn't successfully demangle it.  */
  if ((options & DMGL_PARAMS) != 0 && d_peek_char (&di) != '\0')
    dc = NULL;

  free (di.subs);

  if (dc != NULL)
    *mem = di.comps;
  else
    free (di.comps);

  return dc;
}
