2010-05-13 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gdb / cp-abi.c
CommitLineData
015a42b4 1/* Generic code for supporting multiple C++ ABI's
06c4d4dc 2
4c38e0a4 3 Copyright (C) 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010
6aba47ca 4 Free Software Foundation, Inc.
015a42b4
JB
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
015a42b4
JB
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
015a42b4
JB
20
21#include "defs.h"
22#include "value.h"
23#include "cp-abi.h"
fe1f4a5e 24#include "command.h"
7093c834 25#include "exceptions.h"
fe1f4a5e
DJ
26#include "gdbcmd.h"
27#include "ui-out.h"
28
309367d4 29#include "gdb_string.h"
015a42b4 30
fe1f4a5e 31static struct cp_abi_ops *find_cp_abi (const char *short_name);
015a42b4 32
fe1f4a5e
DJ
33static struct cp_abi_ops current_cp_abi = { "", NULL };
34static struct cp_abi_ops auto_cp_abi = { "auto", NULL };
015a42b4 35
fe1f4a5e
DJ
36#define CP_ABI_MAX 8
37static struct cp_abi_ops *cp_abis[CP_ABI_MAX];
38static int num_cp_abis = 0;
015a42b4
JB
39
40enum ctor_kinds
41is_constructor_name (const char *name)
42{
43 if ((current_cp_abi.is_constructor_name) == NULL)
8a3fe4f8 44 error (_("ABI doesn't define required function is_constructor_name"));
015a42b4
JB
45 return (*current_cp_abi.is_constructor_name) (name);
46}
47
48enum dtor_kinds
49is_destructor_name (const char *name)
50{
51 if ((current_cp_abi.is_destructor_name) == NULL)
8a3fe4f8 52 error (_("ABI doesn't define required function is_destructor_name"));
015a42b4
JB
53 return (*current_cp_abi.is_destructor_name) (name);
54}
55
56int
57is_vtable_name (const char *name)
58{
59 if ((current_cp_abi.is_vtable_name) == NULL)
8a3fe4f8 60 error (_("ABI doesn't define required function is_vtable_name"));
015a42b4
JB
61 return (*current_cp_abi.is_vtable_name) (name);
62}
63
64int
65is_operator_name (const char *name)
66{
67 if ((current_cp_abi.is_operator_name) == NULL)
8a3fe4f8 68 error (_("ABI doesn't define required function is_operator_name"));
015a42b4
JB
69 return (*current_cp_abi.is_operator_name) (name);
70}
71
1514d34e 72int
06c4d4dc 73baseclass_offset (struct type *type, int index, const bfd_byte *valaddr,
1514d34e
DJ
74 CORE_ADDR address)
75{
76 if (current_cp_abi.baseclass_offset == NULL)
8a3fe4f8 77 error (_("ABI doesn't define required function baseclass_offset"));
1514d34e
DJ
78 return (*current_cp_abi.baseclass_offset) (type, index, valaddr, address);
79}
80
e933e538 81struct value *
fe1f4a5e
DJ
82value_virtual_fn_field (struct value **arg1p, struct fn_field *f, int j,
83 struct type *type, int offset)
015a42b4
JB
84{
85 if ((current_cp_abi.virtual_fn_field) == NULL)
86 return NULL;
87 return (*current_cp_abi.virtual_fn_field) (arg1p, f, j, type, offset);
88}
1514d34e 89
015a42b4 90struct type *
e933e538 91value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
015a42b4 92{
7093c834
PP
93 struct type *ret = NULL;
94 struct gdb_exception e;
015a42b4
JB
95 if ((current_cp_abi.rtti_type) == NULL)
96 return NULL;
7093c834
PP
97 TRY_CATCH (e, RETURN_MASK_ERROR)
98 {
99 ret = (*current_cp_abi.rtti_type) (v, full, top, using_enc);
100 }
101 if (e.reason < 0)
102 return NULL;
103 return ret;
015a42b4
JB
104}
105
0d5de010
DJ
106void
107cplus_print_method_ptr (const gdb_byte *contents, struct type *type,
108 struct ui_file *stream)
109{
110 if (current_cp_abi.print_method_ptr == NULL)
111 error (_("GDB does not support pointers to methods on this target"));
112 (*current_cp_abi.print_method_ptr) (contents, type, stream);
113}
114
115int
ad4820ab 116cplus_method_ptr_size (struct type *to_type)
0d5de010
DJ
117{
118 if (current_cp_abi.method_ptr_size == NULL)
119 error (_("GDB does not support pointers to methods on this target"));
ad4820ab 120 return (*current_cp_abi.method_ptr_size) (to_type);
0d5de010
DJ
121}
122
123void
ad4820ab
UW
124cplus_make_method_ptr (struct type *type, gdb_byte *contents,
125 CORE_ADDR value, int is_virtual)
0d5de010
DJ
126{
127 if (current_cp_abi.make_method_ptr == NULL)
128 error (_("GDB does not support pointers to methods on this target"));
ad4820ab 129 (*current_cp_abi.make_method_ptr) (type, contents, value, is_virtual);
0d5de010
DJ
130}
131
b18be20d 132CORE_ADDR
52f729a7 133cplus_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
b18be20d
DJ
134{
135 if (current_cp_abi.skip_trampoline == NULL)
136 return 0;
52f729a7 137 return (*current_cp_abi.skip_trampoline) (frame, stop_pc);
b18be20d
DJ
138}
139
0d5de010
DJ
140struct value *
141cplus_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
142{
143 if (current_cp_abi.method_ptr_to_value == NULL)
144 error (_("GDB does not support pointers to methods on this target"));
145 return (*current_cp_abi.method_ptr_to_value) (this_p, method_ptr);
146}
147
41f1b697
DJ
148int
149cp_pass_by_reference (struct type *type)
150{
151 if ((current_cp_abi.pass_by_reference) == NULL)
152 return 0;
153 return (*current_cp_abi.pass_by_reference) (type);
154}
155
fe1f4a5e
DJ
156/* Set the current C++ ABI to SHORT_NAME. */
157
158static int
159switch_to_cp_abi (const char *short_name)
160{
161 struct cp_abi_ops *abi;
162
163 abi = find_cp_abi (short_name);
164 if (abi == NULL)
165 return 0;
166
167 current_cp_abi = *abi;
168 return 1;
169}
170
171/* Add ABI to the list of supported C++ ABI's. */
172
015a42b4 173int
fe1f4a5e 174register_cp_abi (struct cp_abi_ops *abi)
015a42b4 175{
fe1f4a5e
DJ
176 if (num_cp_abis == CP_ABI_MAX)
177 internal_error (__FILE__, __LINE__,
e2e0b3e5 178 _("Too many C++ ABIs, please increase CP_ABI_MAX in cp-abi.c"));
fe1f4a5e 179
015a42b4
JB
180 cp_abis[num_cp_abis++] = abi;
181
182 return 1;
fe1f4a5e
DJ
183}
184
185/* Set the ABI to use in "auto" mode to SHORT_NAME. */
015a42b4 186
fe1f4a5e
DJ
187void
188set_cp_abi_as_auto_default (const char *short_name)
189{
190 char *new_longname, *new_doc;
191 struct cp_abi_ops *abi = find_cp_abi (short_name);
192
193 if (abi == NULL)
194 internal_error (__FILE__, __LINE__,
e2e0b3e5 195 _("Cannot find C++ ABI \"%s\" to set it as auto default."),
fe1f4a5e
DJ
196 short_name);
197
198 if (auto_cp_abi.longname != NULL)
199 xfree ((char *) auto_cp_abi.longname);
200 if (auto_cp_abi.doc != NULL)
201 xfree ((char *) auto_cp_abi.doc);
202
203 auto_cp_abi = *abi;
204
205 auto_cp_abi.shortname = "auto";
0dfdb8ba 206 new_longname = xstrprintf ("currently \"%s\"", abi->shortname);
fe1f4a5e
DJ
207 auto_cp_abi.longname = new_longname;
208
0dfdb8ba 209 new_doc = xstrprintf ("Automatically selected; currently \"%s\"",
049742da 210 abi->shortname);
fe1f4a5e
DJ
211 auto_cp_abi.doc = new_doc;
212
213 /* Since we copy the current ABI into current_cp_abi instead of
214 using a pointer, if auto is currently the default, we need to
215 reset it. */
216 if (strcmp (current_cp_abi.shortname, "auto") == 0)
217 switch_to_cp_abi ("auto");
015a42b4
JB
218}
219
fe1f4a5e
DJ
220/* Return the ABI operations associated with SHORT_NAME. */
221
222static struct cp_abi_ops *
223find_cp_abi (const char *short_name)
015a42b4
JB
224{
225 int i;
fe1f4a5e 226
015a42b4 227 for (i = 0; i < num_cp_abis; i++)
fe1f4a5e
DJ
228 if (strcmp (cp_abis[i]->shortname, short_name) == 0)
229 return cp_abis[i];
230
231 return NULL;
015a42b4
JB
232}
233
fe1f4a5e
DJ
234/* Display the list of registered C++ ABIs. */
235
236static void
237list_cp_abis (int from_tty)
238{
239 struct cleanup *cleanup_chain;
240 int i;
241 ui_out_text (uiout, "The available C++ ABIs are:\n");
242
243 cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "cp-abi-list");
244 for (i = 0; i < num_cp_abis; i++)
245 {
246 char pad[14];
247 int padcount;
248
249 ui_out_text (uiout, " ");
250 ui_out_field_string (uiout, "cp-abi", cp_abis[i]->shortname);
251
252 padcount = 16 - 2 - strlen (cp_abis[i]->shortname);
253 pad[padcount] = 0;
254 while (padcount > 0)
255 pad[--padcount] = ' ';
256 ui_out_text (uiout, pad);
257
258 ui_out_field_string (uiout, "doc", cp_abis[i]->doc);
259 ui_out_text (uiout, "\n");
260 }
261 do_cleanups (cleanup_chain);
262}
263
264/* Set the current C++ ABI, or display the list of options if no
265 argument is given. */
266
267static void
268set_cp_abi_cmd (char *args, int from_tty)
269{
270 if (args == NULL)
271 {
272 list_cp_abis (from_tty);
273 return;
274 }
275
276 if (!switch_to_cp_abi (args))
8a3fe4f8 277 error (_("Could not find \"%s\" in ABI list"), args);
fe1f4a5e
DJ
278}
279
280/* Show the currently selected C++ ABI. */
281
282static void
283show_cp_abi_cmd (char *args, int from_tty)
284{
285 ui_out_text (uiout, "The currently selected C++ ABI is \"");
286
287 ui_out_field_string (uiout, "cp-abi", current_cp_abi.shortname);
288 ui_out_text (uiout, "\" (");
289 ui_out_field_string (uiout, "longname", current_cp_abi.longname);
290 ui_out_text (uiout, ").\n");
291}
292
b9362cc7
AC
293extern initialize_file_ftype _initialize_cp_abi; /* -Wmissing-prototypes */
294
fe1f4a5e
DJ
295void
296_initialize_cp_abi (void)
297{
298 register_cp_abi (&auto_cp_abi);
299 switch_to_cp_abi ("auto");
300
1a966eab
AC
301 add_cmd ("cp-abi", class_obscure, set_cp_abi_cmd, _("\
302Set the ABI used for inspecting C++ objects.\n\
303\"set cp-abi\" with no arguments will list the available ABIs."),
fe1f4a5e
DJ
304 &setlist);
305
306 add_cmd ("cp-abi", class_obscure, show_cp_abi_cmd,
1a966eab 307 _("Show the ABI used for inspecting C++ objects."), &showlist);
fe1f4a5e 308}
This page took 0.647211 seconds and 4 git commands to generate.