@@ -256,6 +256,54 @@ struct extension_language_ops
changed or an error occurs no further languages are called. */
enum ext_lang_rc (*before_prompt) (const struct extension_language_defn *,
const char *current_gdb_prompt);
+
+ /* Debug method support:
+ clone_debug_method_worker_data, free_debug_method_worker_data,
+ get_matching_debug_method_workers, get_debug_method_arg_types,
+ invoke_debug_method.
+ These methods are optional and may be NULL, but if one of them is
+ implemented then they all must be. */
+
+ /* Clone DATA and return a new but identical debug method worker data
+ object for this extension language. */
+ void * (*clone_debug_method_worker_data) (
+ const struct extension_language_defn *extlang, void *data);
+
+ /* Free the DATA object of this extension language. */
+ void (*free_debug_method_worker_data) (
+ const struct extension_language_defn *extlang, void *data);
+
+ /* Return a vector of matching debug method workers defined in this
+ extension language. The workers service methods with name
+ METHOD_NAME on objects of type OBJ_TYPE. The vector is returned
+ in DM_VEC. */
+ enum ext_lang_rc (*get_matching_debug_method_workers) (
+ const struct extension_language_defn *extlang,
+ struct type *obj_type,
+ const char *method_name,
+ debug_method_worker_vec **dm_vec);
+
+ /* Given a WORKER servicing a particular method, return the types
+ of the arguments the method takes. The number of arguments is
+ returned in NARGS, and their types are returned in the array
+ ARGTYPES. */
+ enum ext_lang_rc (*get_debug_method_arg_types) (
+ const struct extension_language_defn *extlang,
+ struct debug_method_worker *worker,
+ int *nargs,
+ struct type ***arg_types);
+
+ /* Invoke the debug method serviced by WORKER. The method is invoked
+ on OBJECT with arguments in the array ARGS. NARGS is the length of
+ this array. The value returned by the method is returned in
+ RESULT. */
+ enum ext_lang_rc (*invoke_debug_method) (
+ const struct extension_language_defn *extlang,
+ struct debug_method_worker *worker,
+ struct value *object,
+ struct value **args,
+ int nargs,
+ struct value **result);
};
/* State necessary to restore a signal handler to its previous value. */
@@ -834,6 +834,175 @@ check_quit_flag (void)
return result;
}
+/* Debug method support. */
+
+/* Debug method API routines do not have "ext_lang" in the name because
+the name "debug_method" implies that this routine deals with extension
+languages. Plus some of the methods take a debug_method_foo * "self/this"
+arg, not an extension_language_defn * arg. */
+
+static void free_debug_method_worker_vec (void *vec);
+
+/* Returns a new debug_method_worker with EXTLANG and DATA. Space for the
+ result is allocated using malloc. Caller must free. */
+
+struct debug_method_worker *
+new_debug_method_worker (const struct extension_language_defn *extlang,
+ void *data)
+{
+ struct debug_method_worker *worker = XCNEW (struct debug_method_worker);
+
+ worker->extlang = extlang;
+ worker->data = data;
+
+ return worker;
+}
+
+/* Clones WORKER and returns a new but identical worker.
+ The function get_matching_debug_method_workers (see below), returns a
+ vector of matching workers. If a particular worker is selected by GDB
+ to invoke a method, then this function can help in cloning the
+ selected worker and freeing up the vector via a cleanup (see
+ make_debug_method_worker_vec_cleanup below).
+
+ Space for the result is allocated using malloc. Caller must free. */
+
+struct debug_method_worker *
+clone_debug_method_worker (struct debug_method_worker *worker)
+{
+ struct debug_method_worker *new_worker;
+ const struct extension_language_defn *extlang = worker->extlang;
+
+ gdb_assert (extlang->ops->clone_debug_method_worker_data != NULL);
+
+ new_worker = new_debug_method_worker (
+ extlang,
+ extlang->ops->clone_debug_method_worker_data (extlang, worker->data));
+
+ return new_worker;
+}
+
+/* If a method with name METHOD_NAME is to be invoked on an object of type
+ TYPE, then all entension languages are searched for implementations of
+ methods with name METHOD. All matches found are returned as a vector
+ of 'debug_method_worker_ptr' objects. If no matching methods are
+ found, NULL is returned. */
+
+VEC (debug_method_worker_ptr) *
+get_matching_debug_method_workers (struct type *type, const char *method_name)
+{
+ VEC (debug_method_worker_ptr) *workers = NULL;
+ int i;
+ const struct extension_language_defn *extlang;
+
+ ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+ {
+ VEC (debug_method_worker_ptr) *lang_workers, *new_vec;
+ enum ext_lang_rc rc;
+
+ /* If an extension language does not support debug methods, ignore
+ it. */
+ if (extlang->ops->get_matching_debug_method_workers == NULL)
+ continue;
+
+ rc = extlang->ops->get_matching_debug_method_workers (extlang,
+ type, method_name,
+ &lang_workers);
+ if (rc == EXT_LANG_RC_ERROR)
+ {
+ free_debug_method_worker_vec (workers);
+ error (_("Error while looking for matching debug method workers "
+ "defined in %s."), extlang->capitalized_name);
+ }
+
+ new_vec = VEC_merge (debug_method_worker_ptr, workers, lang_workers);
+ /* Free only the vectors and not the elements as NEW_VEC still
+ contains them. */
+ VEC_free (debug_method_worker_ptr, workers);
+ VEC_free (debug_method_worker_ptr, lang_workers);
+ workers = new_vec;
+ }
+
+ return workers;
+}
+
+/* Return the arg types of the debug method encapsulated in WORKER.
+ An array of arg types is returned. The length of the array is returned in
+ NARGS. The type of the 'this' object is returned as the first element of
+ array. */
+
+struct type **
+get_debug_method_arg_types (struct debug_method_worker *worker, int *nargs)
+{
+ enum ext_lang_rc rc;
+ struct type **type_array = NULL;
+ const struct extension_language_defn *extlang = worker->extlang;
+
+ gdb_assert (extlang->ops->get_debug_method_arg_types != NULL);
+
+ rc = extlang->ops->get_debug_method_arg_types (extlang, worker, nargs,
+ &type_array);
+ if (rc == EXT_LANG_RC_ERROR)
+ {
+ error (_("Error while looking for arg types of a debug method worker "
+ "defined in %s."), extlang->capitalized_name);
+ }
+
+ return type_array;
+}
+
+/* Invokes the debug method encapsulated in WORKER and returns the result.
+ The method is invoked on OBJ with arguments in the ARGS array. NARGS is
+ the length of the this array. */
+
+struct value *
+invoke_debug_method (struct debug_method_worker *worker, struct value *obj,
+ struct value **args, int nargs)
+{
+ struct value *result = NULL;
+ enum ext_lang_rc rc;
+
+ gdb_assert (worker->extlang->ops->invoke_debug_method != NULL);
+
+ rc = worker->extlang->ops->invoke_debug_method (worker->extlang, worker,
+ obj, args, nargs, &result);
+ if (rc == EXT_LANG_RC_ERROR)
+ {
+ error (_("Error while invoking a debug method defined in %s"),
+ worker->extlang->capitalized_name);
+ }
+
+ return result;
+}
+
+/* Frees a vector of debug_method_workers VEC. */
+
+static void
+free_debug_method_worker_vec (void *vec)
+{
+ int i;
+ struct debug_method_worker *worker;
+ VEC (debug_method_worker_ptr) *v = (VEC (debug_method_worker_ptr) *) vec;
+
+ for (i = 0; VEC_iterate (debug_method_worker_ptr, v, i, worker); i++)
+ {
+ gdb_assert (worker->extlang->ops->free_debug_method_worker_data != NULL);
+ worker->extlang->ops->free_debug_method_worker_data (worker->extlang,
+ worker->data);
+ xfree (worker);
+ }
+
+ VEC_free (debug_method_worker_ptr, v);
+}
+
+/* Return a cleanup object to free the vector VEC of debug method workers. */
+
+struct cleanup *
+make_debug_method_worker_vec_cleanup (VEC (debug_method_worker_ptr) *vec)
+{
+ return make_cleanup (free_debug_method_worker_vec, (void *) vec);
+}
+
/* Called via an observer before gdb prints its prompt.
Iterate over the extension languages giving them a chance to
change the prompt. The first one to change the prompt wins,
@@ -21,6 +21,7 @@
#define EXTENSION_H
#include "mi/mi-cmds.h" /* For PRINT_NO_VALUES, etc. */
+#include "common/vec.h"
struct breakpoint;
struct command_line;
@@ -33,6 +34,7 @@ struct ui_file;
struct ui_out;
struct value;
struct value_print_options;
+struct debug_method_worker;
/* A function to load and process a script file.
The file has been opened and is ready to be read from the beginning.
@@ -138,6 +140,23 @@ struct ext_lang_type_printers
/* Type-printers from Python. */
void *py_type_printers;
};
+
+/* A type which holds its extension language specific debug method worker
+ data. */
+
+struct debug_method_worker
+{
+ /* The language the debug method worker is implemented in. */
+ const struct extension_language_defn *extlang;
+
+ /* The extension language specific data for this debug method worker. */
+ void *data;
+};
+
+typedef struct debug_method_worker *debug_method_worker_ptr;
+DEF_VEC_P (debug_method_worker_ptr);
+typedef VEC (debug_method_worker_ptr) debug_method_worker_vec;
+
/* The interface for gdb's own extension(/scripting) language. */
extern const struct extension_language_defn extension_language_gdb;
@@ -212,4 +231,23 @@ extern const struct extension_language_defn *get_breakpoint_cond_ext_lang
extern int breakpoint_ext_lang_cond_says_stop (struct breakpoint *);
+extern struct value *invoke_debug_method (struct debug_method_worker *,
+ struct value *,
+ struct value **, int nargs);
+
+extern struct debug_method_worker *clone_debug_method_worker (
+ struct debug_method_worker *);
+
+extern struct debug_method_worker *new_debug_method_worker (
+ const struct extension_language_defn *extlang, void *data);
+
+extern debug_method_worker_vec *get_matching_debug_method_workers (
+ struct type *, const char *);
+
+extern struct type **get_debug_method_arg_types (
+ struct debug_method_worker *, int *);
+
+extern struct cleanup *make_debug_method_worker_vec_cleanup (
+ debug_method_worker_vec *vec);
+
#endif /* EXTENSION_H */