/* Basic C++ demangling support for GDB.

   Copyright (C) 1991-2014 Free Software Foundation, Inc.

   Written by Fred Fish at Cygnus Support.

   This file is part of GDB.

   This program 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 3 of the License, or
   (at your option) any later version.

   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, see <http://www.gnu.org/licenses/>.  */


/*  This file contains support code for C++ demangling that is common
   to a styles of demangling, and GDB specific.  */

#include "defs.h"
#include "command.h"
#include "gdbcmd.h"
#include "demangle.h"
#include "gdb-demangle.h"
/* Select the default C++ demangling style to use.  The default is "auto",
   which allows gdb to attempt to pick an appropriate demangling style for
   the executable it has loaded.  It can be set to a specific style ("gnu",
   "lucid", "arm", "hp", etc.) in which case gdb will never attempt to do auto
   selection of the style unless you do an explicit "set demangle auto".
   To select one of these as the default, set DEFAULT_DEMANGLING_STYLE in
   the appropriate target configuration file.  */

#ifndef DEFAULT_DEMANGLING_STYLE
#define DEFAULT_DEMANGLING_STYLE AUTO_DEMANGLING_STYLE_STRING
#endif

/* See documentation in gdb-demangle.h.  */
int demangle = 1;

static void
show_demangle (struct ui_file *file, int from_tty,
	       struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("Demangling of encoded C++/ObjC names "
		      "when displaying symbols is %s.\n"),
		    value);
}

/* See documentation in gdb-demangle.h.  */
int asm_demangle = 0;

static void
show_asm_demangle (struct ui_file *file, int from_tty,
		   struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("Demangling of C++/ObjC names in "
		      "disassembly listings is %s.\n"),
		    value);
}

/* String name for the current demangling style.  Set by the
   "set demangle-style" command, printed as part of the output by the
   "show demangle-style" command.  */

static const char *current_demangling_style_string;

/* The array of names of the known demanglyng styles.  Generated by
   _initialize_demangler from libiberty_demanglers[] array.  */

static const char **demangling_style_names;
static void
show_demangling_style_names(struct ui_file *file, int from_tty,
			    struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("The current C++ demangling style is \"%s\".\n"),
		    value);
}

/* Set current demangling style.  Called by the "set demangle-style"
   command after it has updated the current_demangling_style_string to
   match what the user has entered.

   If the user has entered a string that matches a known demangling style
   name in the demanglers[] array then just leave the string alone and update
   the current_demangling_style enum value to match.

   If the user has entered a string that doesn't match, including an empty
   string, then print a list of the currently known styles and restore
   the current_demangling_style_string to match the current_demangling_style
   enum value.

   Note:  Assumes that current_demangling_style_string always points to
   a malloc'd string, even if it is a null-string.  */

static void
set_demangling_command (char *ignore, int from_tty, struct cmd_list_element *c)
{
  const struct demangler_engine *dem;
  int i;

  /*  First just try to match whatever style name the user supplied with
     one of the known ones.  Don't bother special casing for an empty
     name, we just treat it as any other style name that doesn't match.
     If we match, update the current demangling style enum.  */

  for (dem = libiberty_demanglers, i = 0;
       dem->demangling_style != unknown_demangling; 
       dem++)
    {
      if (strcmp (current_demangling_style_string,
		  dem->demangling_style_name) == 0)
	{
	  current_demangling_style = dem->demangling_style;
	  current_demangling_style_string = demangling_style_names[i];
	  break;
	}
      i++;
    }

  /* We should have found a match, given we only add known styles to
     the enumeration list.  */
  gdb_assert (dem->demangling_style != unknown_demangling);
}

/* G++ uses a special character to indicate certain internal names.  Which
   character it is depends on the platform:
   - Usually '$' on systems where the assembler will accept that
   - Usually '.' otherwise (this includes most sysv4-like systems and most
     ELF targets)
   - Occasionally '_' if neither of the above is usable

   We check '$' first because it is the safest, and '.' often has another
   meaning.  We don't currently try to handle '_' because the precise forms
   of the names are different on those targets.  */

static char cplus_markers[] = {'$', '.', '\0'};

/* See documentation in gdb-demangle.h.  */

int
is_cplus_marker (int c)
{
  return c && strchr (cplus_markers, c) != NULL;
}

extern initialize_file_ftype _initialize_demangler; /* -Wmissing-prototypes */

void
_initialize_demangler (void)
{
  int i, ndems;

  /* Fill the demangling_style_names[] array, and set the default
     demangling style chosen at compilation time.  */
  for (ndems = 0;
       libiberty_demanglers[ndems].demangling_style != unknown_demangling; 
       ndems++)
    ;
  demangling_style_names = xcalloc (ndems + 1, sizeof (char *));
  for (i = 0;
       libiberty_demanglers[i].demangling_style != unknown_demangling; 
       i++)
    {
      demangling_style_names[i]
	= xstrdup (libiberty_demanglers[i].demangling_style_name);

      if (current_demangling_style_string == NULL
	  && strcmp (DEFAULT_DEMANGLING_STYLE, demangling_style_names[i]) == 0)
	current_demangling_style_string = demangling_style_names[i];
    }

  add_setshow_boolean_cmd ("demangle", class_support, &demangle, _("\
Set demangling of encoded C++/ObjC names when displaying symbols."), _("\
Show demangling of encoded C++/ObjC names when displaying symbols."), NULL,
			   NULL,
			   show_demangle,
			   &setprintlist, &showprintlist);

  add_setshow_boolean_cmd ("asm-demangle", class_support, &asm_demangle, _("\
Set demangling of C++/ObjC names in disassembly listings."), _("\
Show demangling of C++/ObjC names in disassembly listings."), NULL,
			   NULL,
			   show_asm_demangle,
			   &setprintlist, &showprintlist);

  add_setshow_enum_cmd ("demangle-style", class_support,
			demangling_style_names,
			&current_demangling_style_string, _("\
Set the current C++ demangling style."), _("\
Show the current C++ demangling style."), _("\
Use `set demangle-style' without arguments for a list of demangling styles."),
			set_demangling_command,
			show_demangling_style_names,
			&setlist, &showlist);
}
