Re: add set cp-abi command

Jim Ingham
2002-03-15T23:53:03Z

Daniel,

Okay, how about this.

I changed the set/show as per set language.

I added an "auto" abi. This ended up being a little tricky because I
don't know the order in which the initializers get run, but this works.

In the process of doing this I got really annoyed that EVERYTHING was
done by copying structures around. If we think that it is really
important to have the current_cp_abi be a structure rather than a
pointer to a structure so there was one less level of indirection,
that's fine. But there is no reason to manage the internal list this
way as well. So I changed cp_abis to be an array of pointers to
cp_abi_ops structures, and had to change the auto-grow mechanism to
account for it.

I also took out the extern def'ns of num_cp_abis, cp_abis and
current_cp_abi out of cp-abi.h. They weren't currently used outside the
module, and if we end up needing to use them, we should provide
interfaces, rather than just poking around at the data.

I haven't written a doc note for this, I have run out of time for this
today, but thought I would give you a look before the day is out...

What do you think of this:

Index: cp-abi.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-abi.c,v
retrieving revision 1.3
diff -c -w -p -r1.3 cp-abi.c
*** cp-abi.c 2002/01/04 18:20:19 1.3
--- cp-abi.c 2002/03/15 23:46:26
***************
*** 21,33 ****
#include "defs.h"
#include "value.h"
#include "cp-abi.h"

! struct cp_abi_ops current_cp_abi;

! struct cp_abi_ops *cp_abis;

! int num_cp_abis = 0;

enum ctor_kinds
is_constructor_name (const char *name)
{
--- 21,41 ----
#include "defs.h"
#include "value.h"
#include "cp-abi.h"
+ #include "command.h"
+ #include "ui-out.h"
+ #include "gdbcmd.h"

! static struct cp_abi_ops current_cp_abi;
! static struct cp_abi_ops auto_cp_abi = {"auto", NULL};

! #define INITIAL_CP_ABI_MAX 8

! static struct cp_abi_ops *orig_cp_abis[INITIAL_CP_ABI_MAX];
! static struct cp_abi_ops **cp_abis = orig_cp_abis;
! static int max_cp_abis = INITIAL_CP_ABI_MAX;

+ static int num_cp_abis = 0;
+
enum ctor_kinds
is_constructor_name (const char *name)
{
*************** value_rtti_type (struct value *v, int *f
*** 87,109 ****
}

int
! register_cp_abi (struct cp_abi_ops abi)
{
! cp_abis =
! xrealloc (cp_abis, (num_cp_abis + 1) * sizeof (struct cp_abi_ops));
cp_abis[num_cp_abis++] = abi;

return 1;

}

int
switch_to_cp_abi (const char *short_name)
{
int i;
for (i = 0; i < num_cp_abis; i++)
! if (strcmp (cp_abis[i].shortname, short_name) == 0)
! current_cp_abi = cp_abis[i];
return 1;
}

--- 95,231 ----
}

int
! register_cp_abi (struct cp_abi_ops *abi)
! {
! if (num_cp_abis == max_cp_abis)
{
! struct cp_abi_ops **new_abi_list;
! int i;
!
! max_cp_abis *= 2;
! new_abi_list = (struct cp_abi_ops **) xmalloc (max_cp_abis *
sizeof (struct cp_abi_ops *));
! for (i = 0; i < num_cp_abis; i++)
! new_abi_list[i] = cp_abis[i];
!
! if (cp_abis != orig_cp_abis)
! xfree (cp_abis);
!
! cp_abis = new_abi_list;
! }
!
cp_abis[num_cp_abis++] = abi;

return 1;

}

+ void
+ set_cp_abi_as_auto_default (struct cp_abi_ops *abi)
+ {
+
+ if (auto_cp_abi.longname != NULL)
+ xfree (auto_cp_abi.longname);
+ auto_cp_abi.longname = (char *) xmalloc (11 + strlen
(abi->shortname));
+ sprintf (auto_cp_abi.longname, "currently %s",
+ abi->shortname);
+
+ if (auto_cp_abi.doc != NULL)
+ xfree (auto_cp_abi.doc);
+ auto_cp_abi.doc = (char *) xmalloc (11 + strlen (abi->shortname));
+ sprintf (auto_cp_abi.doc, "currently %s",
+ abi->shortname);
+
+ auto_cp_abi.is_destructor_name = abi->is_destructor_name;
+ auto_cp_abi.is_constructor_name = abi->is_constructor_name;
+ auto_cp_abi.is_vtable_name = abi->is_vtable_name;
+ auto_cp_abi.is_operator_name = abi->is_operator_name;
+ auto_cp_abi.virtual_fn_field = abi->virtual_fn_field;
+ auto_cp_abi.rtti_type = abi->rtti_type;
+ auto_cp_abi.baseclass_offset = abi->baseclass_offset;
+
+ /* Since we copy the current ABI into current_cp_abi instead of using
+ a pointer, if auto is currently the default, we need to reset
it. */
+
+ if (cp_abi_is_auto_p ())
+ switch_to_cp_abi ("auto");
+ }
+
+ int
+ cp_abi_is_auto_p ()
+ {
+ if (strcmp (current_cp_abi.shortname, "auto") == 0)
+ return 1;
+ else
+ return 0;
+ }
+
int
switch_to_cp_abi (const char *short_name)
{
int i;
+
for (i = 0; i < num_cp_abis; i++)
! if (strcmp (cp_abis[i]->shortname, short_name) == 0)
! {
! current_cp_abi = *cp_abis[i];
return 1;
}

+ return 0;
+ }
+
+ void
+ show_cp_abis (int from_tty)
+ {
+ int i;
+ ui_out_text (uiout, "The available C++ ABIs are:\n");
+
+ ui_out_tuple_begin (uiout, "cp-abi-list");
+ for (i = 0; i < num_cp_abis; i++)
+ {
+ ui_out_field_string (uiout, "cp-abi", cp_abis[i]->shortname);
+ ui_out_text_fmt (uiout, " - %s\n", cp_abis[i]->doc);
+ }
+ ui_out_tuple_end (uiout);
+
+ }
+
+ void
+ set_cp_abi_cmd (char *args, int from_tty)
+ {
+
+ if (args == NULL)
+ {
+ show_cp_abis (from_tty);
+ return;
+ }
+
+ if (!switch_to_cp_abi (args))
+ error ("Could not find ABI: \"%s\" in ABI list\n", args);
+ }
+
+ void
+ show_cp_abi_cmd (char *args, int from_tty)
+ {
+ ui_out_text (uiout, "The currently selected C++ abi is: ");
+
+ ui_out_field_string (uiout, "cp-abi", current_cp_abi.shortname);
+ ui_out_text (uiout, ".\n");
+ }
+
+ void
+ _initialize_cp_abi (void)
+ {
+ struct cmd_list_element *cmd;
+
+ register_cp_abi (&auto_cp_abi);
+ switch_to_cp_abi ("auto");
+
+ cmd = add_cmd ("cp-abi", class_obscure , set_cp_abi_cmd,
+ "Set the ABI used for inspecting C++ objects.\n\
+ \"set cp-abi\" with no arguments will list the available ABIs.",
&setlist);
+
+ cmd = add_cmd ("cp-abi", class_obscure, show_cp_abi_cmd,
+ "Show the ABI used for inspecting C++ objects.",
&showlist);
+
+ }
Index: cp-abi.h
===================================================================
RCS file: /cvs/src/src/gdb/cp-abi.h,v
retrieving revision 1.4
diff -c -w -p -r1.4 cp-abi.h
*** cp-abi.h 2002/01/04 18:20:19 1.4
--- cp-abi.h 2002/03/15 23:46:28
*************** extern int baseclass_offset (struct type
*** 146,153 ****
struct cp_abi_ops
{
const char *shortname;
! const char *longname;
! const char *doc;

/* ABI-specific implementations for the functions declared above. */
enum ctor_kinds (*is_constructor_name) (const char *name);
--- 146,153 ----
struct cp_abi_ops
{
const char *shortname;
! char *longname; /* These two can't be const, because I need to */
! char *doc; /* change the name for the auto abi. */

/* ABI-specific implementations for the functions declared above. */
enum ctor_kinds (*is_constructor_name) (const char *name);
*************** struct cp_abi_ops
*** 163,173 ****
};

! extern struct cp_abi_ops *cp_abis;
! extern int num_cp_abis;
! extern struct cp_abi_ops current_cp_abi;
! extern int register_cp_abi (struct cp_abi_ops abi);
extern int switch_to_cp_abi (const char *short_name);

#endif

--- 163,172 ----
};

! extern int register_cp_abi (struct cp_abi_ops *abi);
extern int switch_to_cp_abi (const char *short_name);
+ extern void set_cp_abi_as_auto_default (struct cp_abi_ops *abi);
+ extern int cp_abi_is_auto_p ();

#endif

Index: gnu-v2-abi.c
===================================================================
RCS file: /cvs/src/src/gdb/gnu-v2-abi.c,v
retrieving revision 1.6
diff -c -w -p -r1.6 gnu-v2-abi.c
*** gnu-v2-abi.c 2002/01/04 18:20:19 1.6
--- gnu-v2-abi.c 2002/03/15 23:46:28
*************** void
*** 424,429 ****
_initialize_gnu_v2_abi (void)
{
init_gnuv2_ops ();
! register_cp_abi (gnu_v2_abi_ops);
! switch_to_cp_abi ("gnu-v2");
}
--- 424,429 ----
_initialize_gnu_v2_abi (void)
{
init_gnuv2_ops ();
! register_cp_abi (&gnu_v2_abi_ops);
! set_cp_abi_as_auto_default (&gnu_v2_abi_ops);
}
Index: gnu-v3-abi.c
===================================================================
RCS file: /cvs/src/src/gdb/gnu-v3-abi.c,v
retrieving revision 1.8
diff -c -w -p -r1.8 gnu-v3-abi.c
*** gnu-v3-abi.c 2002/02/02 00:04:46 1.8
--- gnu-v3-abi.c 2002/03/15 23:46:28
*************** _initialize_gnu_v3_abi (void)
*** 430,434 ****
{
init_gnuv3_ops ();

! register_cp_abi (gnu_v3_abi_ops);
}
--- 430,434 ----
{
init_gnuv3_ops ();

! register_cp_abi (&gnu_v3_abi_ops);
}
Index: hpacc-abi.c
===================================================================
RCS file: /cvs/src/src/gdb/hpacc-abi.c,v
retrieving revision 1.3
diff -c -w -p -r1.3 hpacc-abi.c
*** hpacc-abi.c 2002/01/04 18:20:19 1.3
--- hpacc-abi.c 2002/03/15 23:46:28
*************** _initialize_hpacc_abi (void)
*** 324,328 ****
regcomp (&operator_pattern,
"^This will never match anything, please fill it in$",
REG_NOSUB);

! register_cp_abi (hpacc_abi_ops);
}
--- 324,328 ----
regcomp (&operator_pattern,
"^This will never match anything, please fill it in$",
REG_NOSUB);

! register_cp_abi (&hpacc_abi_ops);
}
Index: minsyms.c
===================================================================
RCS file: /cvs/src/src/gdb/minsyms.c,v
retrieving revision 1.19
diff -c -w -p -r1.19 minsyms.c
*** minsyms.c 2001/12/10 22:04:10 1.19
--- minsyms.c 2002/03/15 23:46:28
*************** install_minimal_symbols (struct objfile
*** 970,975 ****
--- 970,976 ----
const char *name = SYMBOL_NAME (&objfile->msymbols[i]);
if (name[0] == '_' && name[1] == 'Z')
{
+ if (cp_abi_is_auto_p ())
switch_to_cp_abi ("gnu-v3");
break;
}

Jim
--
Jim Ingham jingham@apple.com
Developer Tools - gdb
Apple Computer