OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [cp-abi.c] - Diff between revs 157 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 157 Rev 816
/* Generic code for supporting multiple C++ ABI's
/* Generic code for supporting multiple C++ ABI's
 
 
   Copyright (C) 2001, 2002, 2003, 2005, 2006, 2007, 2008
   Copyright (C) 2001, 2002, 2003, 2005, 2006, 2007, 2008
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
 
 
   This file is part of GDB.
   This file is part of GDB.
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
#include "defs.h"
#include "defs.h"
#include "value.h"
#include "value.h"
#include "cp-abi.h"
#include "cp-abi.h"
#include "command.h"
#include "command.h"
#include "gdbcmd.h"
#include "gdbcmd.h"
#include "ui-out.h"
#include "ui-out.h"
 
 
#include "gdb_string.h"
#include "gdb_string.h"
 
 
static struct cp_abi_ops *find_cp_abi (const char *short_name);
static struct cp_abi_ops *find_cp_abi (const char *short_name);
 
 
static struct cp_abi_ops current_cp_abi = { "", NULL };
static struct cp_abi_ops current_cp_abi = { "", NULL };
static struct cp_abi_ops auto_cp_abi = { "auto", NULL };
static struct cp_abi_ops auto_cp_abi = { "auto", NULL };
 
 
#define CP_ABI_MAX 8
#define CP_ABI_MAX 8
static struct cp_abi_ops *cp_abis[CP_ABI_MAX];
static struct cp_abi_ops *cp_abis[CP_ABI_MAX];
static int num_cp_abis = 0;
static int num_cp_abis = 0;
 
 
enum ctor_kinds
enum ctor_kinds
is_constructor_name (const char *name)
is_constructor_name (const char *name)
{
{
  if ((current_cp_abi.is_constructor_name) == NULL)
  if ((current_cp_abi.is_constructor_name) == NULL)
    error (_("ABI doesn't define required function is_constructor_name"));
    error (_("ABI doesn't define required function is_constructor_name"));
  return (*current_cp_abi.is_constructor_name) (name);
  return (*current_cp_abi.is_constructor_name) (name);
}
}
 
 
enum dtor_kinds
enum dtor_kinds
is_destructor_name (const char *name)
is_destructor_name (const char *name)
{
{
  if ((current_cp_abi.is_destructor_name) == NULL)
  if ((current_cp_abi.is_destructor_name) == NULL)
    error (_("ABI doesn't define required function is_destructor_name"));
    error (_("ABI doesn't define required function is_destructor_name"));
  return (*current_cp_abi.is_destructor_name) (name);
  return (*current_cp_abi.is_destructor_name) (name);
}
}
 
 
int
int
is_vtable_name (const char *name)
is_vtable_name (const char *name)
{
{
  if ((current_cp_abi.is_vtable_name) == NULL)
  if ((current_cp_abi.is_vtable_name) == NULL)
    error (_("ABI doesn't define required function is_vtable_name"));
    error (_("ABI doesn't define required function is_vtable_name"));
  return (*current_cp_abi.is_vtable_name) (name);
  return (*current_cp_abi.is_vtable_name) (name);
}
}
 
 
int
int
is_operator_name (const char *name)
is_operator_name (const char *name)
{
{
  if ((current_cp_abi.is_operator_name) == NULL)
  if ((current_cp_abi.is_operator_name) == NULL)
    error (_("ABI doesn't define required function is_operator_name"));
    error (_("ABI doesn't define required function is_operator_name"));
  return (*current_cp_abi.is_operator_name) (name);
  return (*current_cp_abi.is_operator_name) (name);
}
}
 
 
int
int
baseclass_offset (struct type *type, int index, const bfd_byte *valaddr,
baseclass_offset (struct type *type, int index, const bfd_byte *valaddr,
                  CORE_ADDR address)
                  CORE_ADDR address)
{
{
  if (current_cp_abi.baseclass_offset == NULL)
  if (current_cp_abi.baseclass_offset == NULL)
    error (_("ABI doesn't define required function baseclass_offset"));
    error (_("ABI doesn't define required function baseclass_offset"));
  return (*current_cp_abi.baseclass_offset) (type, index, valaddr, address);
  return (*current_cp_abi.baseclass_offset) (type, index, valaddr, address);
}
}
 
 
struct value *
struct value *
value_virtual_fn_field (struct value **arg1p, struct fn_field *f, int j,
value_virtual_fn_field (struct value **arg1p, struct fn_field *f, int j,
                        struct type *type, int offset)
                        struct type *type, int offset)
{
{
  if ((current_cp_abi.virtual_fn_field) == NULL)
  if ((current_cp_abi.virtual_fn_field) == NULL)
    return NULL;
    return NULL;
  return (*current_cp_abi.virtual_fn_field) (arg1p, f, j, type, offset);
  return (*current_cp_abi.virtual_fn_field) (arg1p, f, j, type, offset);
}
}
 
 
struct type *
struct type *
value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
{
{
  if ((current_cp_abi.rtti_type) == NULL)
  if ((current_cp_abi.rtti_type) == NULL)
    return NULL;
    return NULL;
  return (*current_cp_abi.rtti_type) (v, full, top, using_enc);
  return (*current_cp_abi.rtti_type) (v, full, top, using_enc);
}
}
 
 
void
void
cplus_print_method_ptr (const gdb_byte *contents, struct type *type,
cplus_print_method_ptr (const gdb_byte *contents, struct type *type,
                        struct ui_file *stream)
                        struct ui_file *stream)
{
{
  if (current_cp_abi.print_method_ptr == NULL)
  if (current_cp_abi.print_method_ptr == NULL)
    error (_("GDB does not support pointers to methods on this target"));
    error (_("GDB does not support pointers to methods on this target"));
  (*current_cp_abi.print_method_ptr) (contents, type, stream);
  (*current_cp_abi.print_method_ptr) (contents, type, stream);
}
}
 
 
int
int
cplus_method_ptr_size (void)
cplus_method_ptr_size (void)
{
{
  if (current_cp_abi.method_ptr_size == NULL)
  if (current_cp_abi.method_ptr_size == NULL)
    error (_("GDB does not support pointers to methods on this target"));
    error (_("GDB does not support pointers to methods on this target"));
  return (*current_cp_abi.method_ptr_size) ();
  return (*current_cp_abi.method_ptr_size) ();
}
}
 
 
void
void
cplus_make_method_ptr (gdb_byte *contents, CORE_ADDR value, int is_virtual)
cplus_make_method_ptr (gdb_byte *contents, CORE_ADDR value, int is_virtual)
{
{
  if (current_cp_abi.make_method_ptr == NULL)
  if (current_cp_abi.make_method_ptr == NULL)
    error (_("GDB does not support pointers to methods on this target"));
    error (_("GDB does not support pointers to methods on this target"));
  (*current_cp_abi.make_method_ptr) (contents, value, is_virtual);
  (*current_cp_abi.make_method_ptr) (contents, value, is_virtual);
}
}
 
 
CORE_ADDR
CORE_ADDR
cplus_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
cplus_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
{
{
  if (current_cp_abi.skip_trampoline == NULL)
  if (current_cp_abi.skip_trampoline == NULL)
    return 0;
    return 0;
  return (*current_cp_abi.skip_trampoline) (frame, stop_pc);
  return (*current_cp_abi.skip_trampoline) (frame, stop_pc);
}
}
 
 
struct value *
struct value *
cplus_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
cplus_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
{
{
  if (current_cp_abi.method_ptr_to_value == NULL)
  if (current_cp_abi.method_ptr_to_value == NULL)
    error (_("GDB does not support pointers to methods on this target"));
    error (_("GDB does not support pointers to methods on this target"));
  return (*current_cp_abi.method_ptr_to_value) (this_p, method_ptr);
  return (*current_cp_abi.method_ptr_to_value) (this_p, method_ptr);
}
}
 
 
int
int
cp_pass_by_reference (struct type *type)
cp_pass_by_reference (struct type *type)
{
{
  if ((current_cp_abi.pass_by_reference) == NULL)
  if ((current_cp_abi.pass_by_reference) == NULL)
    return 0;
    return 0;
  return (*current_cp_abi.pass_by_reference) (type);
  return (*current_cp_abi.pass_by_reference) (type);
}
}
 
 
/* Set the current C++ ABI to SHORT_NAME.  */
/* Set the current C++ ABI to SHORT_NAME.  */
 
 
static int
static int
switch_to_cp_abi (const char *short_name)
switch_to_cp_abi (const char *short_name)
{
{
  struct cp_abi_ops *abi;
  struct cp_abi_ops *abi;
 
 
  abi = find_cp_abi (short_name);
  abi = find_cp_abi (short_name);
  if (abi == NULL)
  if (abi == NULL)
    return 0;
    return 0;
 
 
  current_cp_abi = *abi;
  current_cp_abi = *abi;
  return 1;
  return 1;
}
}
 
 
/* Add ABI to the list of supported C++ ABI's.  */
/* Add ABI to the list of supported C++ ABI's.  */
 
 
int
int
register_cp_abi (struct cp_abi_ops *abi)
register_cp_abi (struct cp_abi_ops *abi)
{
{
  if (num_cp_abis == CP_ABI_MAX)
  if (num_cp_abis == CP_ABI_MAX)
    internal_error (__FILE__, __LINE__,
    internal_error (__FILE__, __LINE__,
                    _("Too many C++ ABIs, please increase CP_ABI_MAX in cp-abi.c"));
                    _("Too many C++ ABIs, please increase CP_ABI_MAX in cp-abi.c"));
 
 
  cp_abis[num_cp_abis++] = abi;
  cp_abis[num_cp_abis++] = abi;
 
 
  return 1;
  return 1;
}
}
 
 
/* Set the ABI to use in "auto" mode to SHORT_NAME.  */
/* Set the ABI to use in "auto" mode to SHORT_NAME.  */
 
 
void
void
set_cp_abi_as_auto_default (const char *short_name)
set_cp_abi_as_auto_default (const char *short_name)
{
{
  char *new_longname, *new_doc;
  char *new_longname, *new_doc;
  struct cp_abi_ops *abi = find_cp_abi (short_name);
  struct cp_abi_ops *abi = find_cp_abi (short_name);
 
 
  if (abi == NULL)
  if (abi == NULL)
    internal_error (__FILE__, __LINE__,
    internal_error (__FILE__, __LINE__,
                    _("Cannot find C++ ABI \"%s\" to set it as auto default."),
                    _("Cannot find C++ ABI \"%s\" to set it as auto default."),
                    short_name);
                    short_name);
 
 
  if (auto_cp_abi.longname != NULL)
  if (auto_cp_abi.longname != NULL)
    xfree ((char *) auto_cp_abi.longname);
    xfree ((char *) auto_cp_abi.longname);
  if (auto_cp_abi.doc != NULL)
  if (auto_cp_abi.doc != NULL)
    xfree ((char *) auto_cp_abi.doc);
    xfree ((char *) auto_cp_abi.doc);
 
 
  auto_cp_abi = *abi;
  auto_cp_abi = *abi;
 
 
  auto_cp_abi.shortname = "auto";
  auto_cp_abi.shortname = "auto";
  new_longname = xstrprintf ("currently \"%s\"", abi->shortname);
  new_longname = xstrprintf ("currently \"%s\"", abi->shortname);
  auto_cp_abi.longname = new_longname;
  auto_cp_abi.longname = new_longname;
 
 
  new_doc = xstrprintf ("Automatically selected; currently \"%s\"",
  new_doc = xstrprintf ("Automatically selected; currently \"%s\"",
             abi->shortname);
             abi->shortname);
  auto_cp_abi.doc = new_doc;
  auto_cp_abi.doc = new_doc;
 
 
  /* Since we copy the current ABI into current_cp_abi instead of
  /* Since we copy the current ABI into current_cp_abi instead of
     using a pointer, if auto is currently the default, we need to
     using a pointer, if auto is currently the default, we need to
     reset it.  */
     reset it.  */
  if (strcmp (current_cp_abi.shortname, "auto") == 0)
  if (strcmp (current_cp_abi.shortname, "auto") == 0)
    switch_to_cp_abi ("auto");
    switch_to_cp_abi ("auto");
}
}
 
 
/* Return the ABI operations associated with SHORT_NAME.  */
/* Return the ABI operations associated with SHORT_NAME.  */
 
 
static struct cp_abi_ops *
static struct cp_abi_ops *
find_cp_abi (const char *short_name)
find_cp_abi (const char *short_name)
{
{
  int i;
  int i;
 
 
  for (i = 0; i < num_cp_abis; i++)
  for (i = 0; i < num_cp_abis; i++)
    if (strcmp (cp_abis[i]->shortname, short_name) == 0)
    if (strcmp (cp_abis[i]->shortname, short_name) == 0)
      return cp_abis[i];
      return cp_abis[i];
 
 
  return NULL;
  return NULL;
}
}
 
 
/* Display the list of registered C++ ABIs.  */
/* Display the list of registered C++ ABIs.  */
 
 
static void
static void
list_cp_abis (int from_tty)
list_cp_abis (int from_tty)
{
{
  struct cleanup *cleanup_chain;
  struct cleanup *cleanup_chain;
  int i;
  int i;
  ui_out_text (uiout, "The available C++ ABIs are:\n");
  ui_out_text (uiout, "The available C++ ABIs are:\n");
 
 
  cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "cp-abi-list");
  cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "cp-abi-list");
  for (i = 0; i < num_cp_abis; i++)
  for (i = 0; i < num_cp_abis; i++)
    {
    {
      char pad[14];
      char pad[14];
      int padcount;
      int padcount;
 
 
      ui_out_text (uiout, "  ");
      ui_out_text (uiout, "  ");
      ui_out_field_string (uiout, "cp-abi", cp_abis[i]->shortname);
      ui_out_field_string (uiout, "cp-abi", cp_abis[i]->shortname);
 
 
      padcount = 16 - 2 - strlen (cp_abis[i]->shortname);
      padcount = 16 - 2 - strlen (cp_abis[i]->shortname);
      pad[padcount] = 0;
      pad[padcount] = 0;
      while (padcount > 0)
      while (padcount > 0)
        pad[--padcount] = ' ';
        pad[--padcount] = ' ';
      ui_out_text (uiout, pad);
      ui_out_text (uiout, pad);
 
 
      ui_out_field_string (uiout, "doc", cp_abis[i]->doc);
      ui_out_field_string (uiout, "doc", cp_abis[i]->doc);
      ui_out_text (uiout, "\n");
      ui_out_text (uiout, "\n");
    }
    }
  do_cleanups (cleanup_chain);
  do_cleanups (cleanup_chain);
}
}
 
 
/* Set the current C++ ABI, or display the list of options if no
/* Set the current C++ ABI, or display the list of options if no
   argument is given.  */
   argument is given.  */
 
 
static void
static void
set_cp_abi_cmd (char *args, int from_tty)
set_cp_abi_cmd (char *args, int from_tty)
{
{
  if (args == NULL)
  if (args == NULL)
    {
    {
      list_cp_abis (from_tty);
      list_cp_abis (from_tty);
      return;
      return;
    }
    }
 
 
  if (!switch_to_cp_abi (args))
  if (!switch_to_cp_abi (args))
    error (_("Could not find \"%s\" in ABI list"), args);
    error (_("Could not find \"%s\" in ABI list"), args);
}
}
 
 
/* Show the currently selected C++ ABI.  */
/* Show the currently selected C++ ABI.  */
 
 
static void
static void
show_cp_abi_cmd (char *args, int from_tty)
show_cp_abi_cmd (char *args, int from_tty)
{
{
  ui_out_text (uiout, "The currently selected C++ ABI is \"");
  ui_out_text (uiout, "The currently selected C++ ABI is \"");
 
 
  ui_out_field_string (uiout, "cp-abi", current_cp_abi.shortname);
  ui_out_field_string (uiout, "cp-abi", current_cp_abi.shortname);
  ui_out_text (uiout, "\" (");
  ui_out_text (uiout, "\" (");
  ui_out_field_string (uiout, "longname", current_cp_abi.longname);
  ui_out_field_string (uiout, "longname", current_cp_abi.longname);
  ui_out_text (uiout, ").\n");
  ui_out_text (uiout, ").\n");
}
}
 
 
extern initialize_file_ftype _initialize_cp_abi; /* -Wmissing-prototypes */
extern initialize_file_ftype _initialize_cp_abi; /* -Wmissing-prototypes */
 
 
void
void
_initialize_cp_abi (void)
_initialize_cp_abi (void)
{
{
  register_cp_abi (&auto_cp_abi);
  register_cp_abi (&auto_cp_abi);
  switch_to_cp_abi ("auto");
  switch_to_cp_abi ("auto");
 
 
  add_cmd ("cp-abi", class_obscure, set_cp_abi_cmd, _("\
  add_cmd ("cp-abi", class_obscure, set_cp_abi_cmd, _("\
Set the ABI used for inspecting C++ objects.\n\
Set the ABI used for inspecting C++ objects.\n\
\"set cp-abi\" with no arguments will list the available ABIs."),
\"set cp-abi\" with no arguments will list the available ABIs."),
           &setlist);
           &setlist);
 
 
  add_cmd ("cp-abi", class_obscure, show_cp_abi_cmd,
  add_cmd ("cp-abi", class_obscure, show_cp_abi_cmd,
           _("Show the ABI used for inspecting C++ objects."), &showlist);
           _("Show the ABI used for inspecting C++ objects."), &showlist);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.