Browse Source
definitions. * macrocmd.c, macroscope.c, macroscope.h: New files. * Makefile.in (SFILES): Add macrocmd.c, macroscope.c. (macroscope_h): New variable. (HFILES_NO_SRCDIR): Add macroscope.h. (COMMON_OBS): Add macrocmd.o, macroscope.o. (macroscope.o, macrocmd.o): New rules.binutils-2_13-branch
5 changed files with 475 additions and 3 deletions
@ -0,0 +1,287 @@ |
|||||
|
/* C preprocessor macro expansion commands for GDB.
|
||||
|
Copyright 2002 Free Software Foundation, Inc. |
||||
|
Contributed by Red Hat, Inc. |
||||
|
|
||||
|
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 2 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, write to the Free Software |
||||
|
Foundation, Inc., 59 Temple Place - Suite 330, |
||||
|
Boston, MA 02111-1307, USA. */ |
||||
|
|
||||
|
|
||||
|
#include "defs.h" |
||||
|
#include "macrotab.h" |
||||
|
#include "macroexp.h" |
||||
|
#include "macroscope.h" |
||||
|
#include "command.h" |
||||
|
#include "gdbcmd.h" |
||||
|
|
||||
|
|
||||
|
/* The `macro' prefix command. */ |
||||
|
|
||||
|
static struct cmd_list_element *macrolist; |
||||
|
|
||||
|
static void |
||||
|
macro_command (char *arg, int from_tty) |
||||
|
{ |
||||
|
printf_unfiltered |
||||
|
("\"macro\" must be followed by the name of a macro command.\n"); |
||||
|
help_list (macrolist, "macro ", -1, gdb_stdout); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/* Macro expansion commands. */ |
||||
|
|
||||
|
|
||||
|
static void |
||||
|
macro_expand_command (char *exp, int from_tty) |
||||
|
{ |
||||
|
struct macro_scope *ms = NULL; |
||||
|
char *expanded = NULL; |
||||
|
struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &ms); |
||||
|
make_cleanup (free_current_contents, &expanded); |
||||
|
|
||||
|
/* You know, when the user doesn't specify any expression, it would be
|
||||
|
really cool if this defaulted to the last expression evaluated. |
||||
|
Then it would be easy to ask, "Hey, what did I just evaluate?" But |
||||
|
at the moment, the `print' commands don't save the last expression |
||||
|
evaluated, just its value. */ |
||||
|
if (! exp || ! *exp) |
||||
|
error ("You must follow the `macro expand' command with the" |
||||
|
" expression you\n" |
||||
|
"want to expand."); |
||||
|
|
||||
|
ms = default_macro_scope (); |
||||
|
if (ms) |
||||
|
{ |
||||
|
expanded = macro_expand (exp, standard_macro_lookup, ms); |
||||
|
fputs_filtered ("expands to: ", gdb_stdout); |
||||
|
fputs_filtered (expanded, gdb_stdout); |
||||
|
fputs_filtered ("\n", gdb_stdout); |
||||
|
} |
||||
|
else |
||||
|
fputs_filtered ("GDB has no preprocessor macro information for " |
||||
|
"that code.\n", |
||||
|
gdb_stdout); |
||||
|
|
||||
|
do_cleanups (cleanup_chain); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void |
||||
|
macro_expand_once_command (char *exp, int from_tty) |
||||
|
{ |
||||
|
struct macro_scope *ms = NULL; |
||||
|
char *expanded = NULL; |
||||
|
struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &ms); |
||||
|
make_cleanup (free_current_contents, &expanded); |
||||
|
|
||||
|
/* You know, when the user doesn't specify any expression, it would be
|
||||
|
really cool if this defaulted to the last expression evaluated. |
||||
|
And it should set the once-expanded text as the new `last |
||||
|
expression'. That way, you could just hit return over and over and |
||||
|
see the expression expanded one level at a time. */ |
||||
|
if (! exp || ! *exp) |
||||
|
error ("You must follow the `macro expand-once' command with" |
||||
|
" the expression\n" |
||||
|
"you want to expand."); |
||||
|
|
||||
|
ms = default_macro_scope (); |
||||
|
if (ms) |
||||
|
{ |
||||
|
expanded = macro_expand_once (exp, standard_macro_lookup, ms); |
||||
|
fputs_filtered ("expands to: ", gdb_stdout); |
||||
|
fputs_filtered (expanded, gdb_stdout); |
||||
|
fputs_filtered ("\n", gdb_stdout); |
||||
|
} |
||||
|
else |
||||
|
fputs_filtered ("GDB has no preprocessor macro information for " |
||||
|
"that code.\n", |
||||
|
gdb_stdout); |
||||
|
|
||||
|
do_cleanups (cleanup_chain); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void |
||||
|
show_pp_source_pos (struct ui_file *stream, |
||||
|
struct macro_source_file *file, |
||||
|
int line) |
||||
|
{ |
||||
|
fprintf_filtered (stream, "%s:%d\n", file->filename, line); |
||||
|
|
||||
|
while (file->included_by) |
||||
|
{ |
||||
|
fprintf_filtered (gdb_stdout, " included at %s:%d\n", |
||||
|
file->included_by->filename, |
||||
|
file->included_at_line); |
||||
|
file = file->included_by; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void |
||||
|
show_macro_command (char *name, int from_tty) |
||||
|
{ |
||||
|
struct macro_scope *ms = NULL; |
||||
|
struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &ms); |
||||
|
struct macro_definition *d; |
||||
|
|
||||
|
if (! name || ! *name) |
||||
|
error ("You must follow the `show macro' command with the name" |
||||
|
" of the macro\n" |
||||
|
"whose definition you want to see."); |
||||
|
|
||||
|
ms = default_macro_scope (); |
||||
|
if (! ms) |
||||
|
error ("GDB has no preprocessor macro information for that code.\n"); |
||||
|
|
||||
|
d = macro_lookup_definition (ms->file, ms->line, name); |
||||
|
if (d) |
||||
|
{ |
||||
|
int line; |
||||
|
struct macro_source_file *file |
||||
|
= macro_definition_location (ms->file, ms->line, name, &line); |
||||
|
|
||||
|
fprintf_filtered (gdb_stdout, "Defined at "); |
||||
|
show_pp_source_pos (gdb_stdout, file, line); |
||||
|
fprintf_filtered (gdb_stdout, "#define %s", name); |
||||
|
if (d->kind == macro_function_like) |
||||
|
{ |
||||
|
int i; |
||||
|
|
||||
|
fputs_filtered ("(", gdb_stdout); |
||||
|
for (i = 0; i < d->argc; i++) |
||||
|
{ |
||||
|
fputs_filtered (d->argv[i], gdb_stdout); |
||||
|
if (i + 1 < d->argc) |
||||
|
fputs_filtered (", ", gdb_stdout); |
||||
|
} |
||||
|
fputs_filtered (")", gdb_stdout); |
||||
|
} |
||||
|
fprintf_filtered (gdb_stdout, " %s\n", d->replacement); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
fprintf_filtered (gdb_stdout, |
||||
|
"The symbol `%s' has no definition as a C/C++" |
||||
|
" preprocessor macro\n" |
||||
|
"at ", name); |
||||
|
show_pp_source_pos (gdb_stdout, ms->file, ms->line); |
||||
|
} |
||||
|
|
||||
|
do_cleanups (cleanup_chain); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/* User-defined macros. */ |
||||
|
|
||||
|
/* A table of user-defined macros. Unlike the macro tables used for
|
||||
|
symtabs, this one uses xmalloc for all its allocation, not an |
||||
|
obstack, and it doesn't bcache anything; it just xmallocs things. So |
||||
|
it's perfectly possible to remove things from this, or redefine |
||||
|
things. */ |
||||
|
static struct macro_table *user_macros; |
||||
|
|
||||
|
static void |
||||
|
macro_define_command (char *exp, int from_tty) |
||||
|
{ |
||||
|
error ("Command not implemented yet."); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void |
||||
|
macro_undef_command (char *exp, int from_tty) |
||||
|
{ |
||||
|
error ("Command not implemented yet."); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void |
||||
|
macro_list_command (char *exp, int from_tty) |
||||
|
{ |
||||
|
error ("Command not implemented yet."); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/* Initializing the `macrocmd' module. */ |
||||
|
|
||||
|
void |
||||
|
_initialize_macrocmd (void) |
||||
|
{ |
||||
|
struct cmd_list_element *c; |
||||
|
|
||||
|
/* We introduce a new command prefix, `macro', under which we'll put
|
||||
|
the various commands for working with preprocessor macros. */ |
||||
|
add_prefix_cmd |
||||
|
("macro", class_info, macro_command, |
||||
|
"Prefix for commands dealing with C preprocessor macros.", |
||||
|
¯olist, "macro ", 0, &cmdlist); |
||||
|
|
||||
|
add_cmd |
||||
|
("expand", no_class, macro_expand_command, |
||||
|
"Fully expand any C/C++ preprocessor macro invocations in EXPRESSION.\n" |
||||
|
"Show the expanded expression.", |
||||
|
¯olist); |
||||
|
add_alias_cmd ("exp", "expand", no_class, 1, ¯olist); |
||||
|
add_cmd |
||||
|
("expand-once", no_class, macro_expand_once_command, |
||||
|
"Expand C/C++ preprocessor macro invocations appearing directly in" |
||||
|
" EXPRESSION.\n" |
||||
|
"Show the expanded expression.\n" |
||||
|
"\n" |
||||
|
"This command differs from `macro expand' in that it only expands macro\n" |
||||
|
"invocations that appear directly in EXPRESSION; if expanding a macro\n" |
||||
|
"introduces further macro invocations, those are left unexpanded.\n" |
||||
|
"\n" |
||||
|
"`macro expand-once' helps you see how a particular macro expands,\n" |
||||
|
"whereas `macro expand' shows you how all the macros involved in an\n" |
||||
|
"expression work together to yield a pre-processed expression.", |
||||
|
¯olist); |
||||
|
add_alias_cmd ("exp1", "expand-once", no_class, 1, ¯olist); |
||||
|
|
||||
|
add_cmd |
||||
|
("macro", no_class, show_macro_command, |
||||
|
"Show the definition of MACRO, and its source location.", |
||||
|
&showlist); |
||||
|
|
||||
|
add_cmd |
||||
|
("define", no_class, macro_define_command, |
||||
|
"Define a new C/C++ preprocessor macro.\n" |
||||
|
"The GDB command `macro define DEFINITION' is equivalent to placing a\n" |
||||
|
"preprocessor directive of the form `#define DEFINITION' such that the\n" |
||||
|
"definition is visible in all the inferior's source files.\n" |
||||
|
"For example:\n" |
||||
|
" (gdb) macro define PI (3.1415926)\n" |
||||
|
" (gdb) macro define MIN(x,y) ((x) < (y) ? (x) : (y))", |
||||
|
¯olist); |
||||
|
|
||||
|
add_cmd |
||||
|
("undef", no_class, macro_undef_command, |
||||
|
"Remove the definition of the C/C++ preprocessor macro with the" |
||||
|
" given name.", |
||||
|
¯olist); |
||||
|
|
||||
|
add_cmd |
||||
|
("list", no_class, macro_list_command, |
||||
|
"List all the macros defined using the `macro define' command.", |
||||
|
¯olist); |
||||
|
|
||||
|
user_macros = new_macro_table (0, 0); |
||||
|
} |
||||
@ -0,0 +1,107 @@ |
|||||
|
/* Functions for deciding which macros are currently in scope.
|
||||
|
Copyright 2002 Free Software Foundation, Inc. |
||||
|
Contributed by Red Hat, Inc. |
||||
|
|
||||
|
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 2 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, write to the Free Software |
||||
|
Foundation, Inc., 59 Temple Place - Suite 330, |
||||
|
Boston, MA 02111-1307, USA. */ |
||||
|
|
||||
|
#include "defs.h" |
||||
|
|
||||
|
#include "macroscope.h" |
||||
|
#include "symtab.h" |
||||
|
#include "target.h" |
||||
|
#include "frame.h" |
||||
|
#include "inferior.h" |
||||
|
|
||||
|
|
||||
|
struct macro_scope * |
||||
|
sal_macro_scope (struct symtab_and_line sal) |
||||
|
{ |
||||
|
struct macro_source_file *main; |
||||
|
struct macro_scope *ms; |
||||
|
|
||||
|
if (! sal.symtab |
||||
|
|| ! sal.symtab->macro_table) |
||||
|
return 0; |
||||
|
|
||||
|
ms = (struct macro_scope *) xmalloc (sizeof (*ms)); |
||||
|
|
||||
|
main = macro_main (sal.symtab->macro_table); |
||||
|
ms->file = macro_lookup_inclusion (main, sal.symtab->filename); |
||||
|
|
||||
|
if (! ms->file) |
||||
|
internal_error |
||||
|
(__FILE__, __LINE__, |
||||
|
"\n" |
||||
|
"the symtab `%s' refers to a preprocessor macro table which doesn't\n" |
||||
|
"have any record of processing a file by that name.\n", |
||||
|
sal.symtab->filename); |
||||
|
|
||||
|
ms->line = sal.line; |
||||
|
|
||||
|
return ms; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
struct macro_scope * |
||||
|
default_macro_scope () |
||||
|
{ |
||||
|
struct symtab_and_line sal; |
||||
|
struct macro_source_file *main; |
||||
|
struct macro_scope *ms; |
||||
|
|
||||
|
/* If there's a selected frame, use its PC. */ |
||||
|
if (selected_frame) |
||||
|
sal = find_pc_line (selected_frame->pc, 0); |
||||
|
|
||||
|
/* If the target has any registers at all, then use its PC. Why we
|
||||
|
would have registers but no stack, I'm not sure. */ |
||||
|
else if (target_has_registers) |
||||
|
sal = find_pc_line (read_pc (), 0); |
||||
|
|
||||
|
/* If all else fails, fall back to the current listing position. */ |
||||
|
else |
||||
|
{ |
||||
|
/* Don't call select_source_symtab here. That can raise an
|
||||
|
error if symbols aren't loaded, but GDB calls the expression |
||||
|
evaluator in all sorts of contexts. |
||||
|
|
||||
|
For example, commands like `set width' call the expression |
||||
|
evaluator to evaluate their numeric arguments. If the |
||||
|
current language is C, then that may call this function to |
||||
|
choose a scope for macro expansion. If you don't have any |
||||
|
symbol files loaded, then select_source_symtab will raise an |
||||
|
error. But `set width' shouldn't raise an error just because |
||||
|
it can't decide which scope to macro-expand its argument in. */ |
||||
|
sal.symtab = current_source_symtab; |
||||
|
sal.line = current_source_line; |
||||
|
} |
||||
|
|
||||
|
return sal_macro_scope (sal); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/* Look up the definition of the macro named NAME in scope at the source
|
||||
|
location given by BATON, which must be a pointer to a `struct |
||||
|
macro_scope' structure. */ |
||||
|
struct macro_definition * |
||||
|
standard_macro_lookup (const char *name, void *baton) |
||||
|
{ |
||||
|
struct macro_scope *ms = (struct macro_scope *) baton; |
||||
|
|
||||
|
return macro_lookup_definition (ms->file, ms->line, name); |
||||
|
} |
||||
@ -0,0 +1,63 @@ |
|||||
|
/* Interface to functions for deciding which macros are currently in scope.
|
||||
|
Copyright 2002 Free Software Foundation, Inc. |
||||
|
Contributed by Red Hat, Inc. |
||||
|
|
||||
|
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 2 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, write to the Free Software |
||||
|
Foundation, Inc., 59 Temple Place - Suite 330, |
||||
|
Boston, MA 02111-1307, USA. */ |
||||
|
|
||||
|
#ifndef MACROSCOPE_H |
||||
|
#define MACROSCOPE_H |
||||
|
|
||||
|
#include "macrotab.h" |
||||
|
#include "symtab.h" |
||||
|
|
||||
|
|
||||
|
/* All the information we need to decide which macro definitions are
|
||||
|
in scope: a source file (either a main source file or an |
||||
|
#inclusion), and a line number in that file. */ |
||||
|
struct macro_scope { |
||||
|
struct macro_source_file *file; |
||||
|
int line; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
/* Return a `struct macro_scope' object corresponding to the symtab
|
||||
|
and line given in SAL. If we have no macro information for that |
||||
|
location, or if SAL's pc is zero, return zero. */ |
||||
|
struct macro_scope *sal_macro_scope (struct symtab_and_line sal); |
||||
|
|
||||
|
|
||||
|
/* Return a `struct macro_scope' object describing the scope the `macro
|
||||
|
expand' and `macro expand-once' commands should use for looking up |
||||
|
macros. If we have a selected frame, this is the source location of |
||||
|
its PC; otherwise, this is the last listing position. |
||||
|
|
||||
|
If we have no macro information for the current location, return zero. |
||||
|
|
||||
|
The object returned is allocated using xmalloc; the caller is |
||||
|
responsible for freeing it. */ |
||||
|
struct macro_scope *default_macro_scope (void); |
||||
|
|
||||
|
|
||||
|
/* Look up the definition of the macro named NAME in scope at the source
|
||||
|
location given by BATON, which must be a pointer to a `struct |
||||
|
macro_scope' structure. This function is suitable for use as |
||||
|
a macro_lookup_ftype function. */ |
||||
|
struct macro_definition *standard_macro_lookup (const char *name, void *baton); |
||||
|
|
||||
|
|
||||
|
#endif /* MACROSCOPE_H */ |
||||
Loading…
Reference in new issue