PR macros/2564:
	* c-exp.y (macro_original_text, expansion_obstack,
	expression_macro_scope): New globals.
	(scan_macro_expansion): New function.
	(scanning_macro_expansion): Likewise.
	(finished_macro_expansion): Likewise.
	(scan_macro_cleanup): Likewise.
	(c_parse): Find macro scope.  Initialize obstack.
	* c-lang.h (scan_macro_expansion, scanning_macro_expansion,
	finished_macro_expansion, expression_macro_lookup_func,
	expression_macro_lookup_baton): Remove.
	* c-lang.c (scan_macro_expansion, scanning_macro_expansion,
	finished_macro_expansion, expression_macro_lookup_func,
	expression_macro_lookup_baton): Remove.
	(macro_original_text, macro_expanded_text,
	c_preprocess_and_parse): Remove.
	(c_language_defn, cplus_language_defn, asm_language_defn,
	minimal_language_defn): Use c_parse.
gdb/testsuite
	* gdb.base/macscp.exp: Print "address.addr".
	* gdb.base/macscp1.c (struct outer): New struct.
	(address): New global.
This commit is contained in:
Tom Tromey 2008-12-11 18:30:28 +00:00
parent df13162329
commit 7c8adf682b
7 changed files with 158 additions and 119 deletions

View File

@ -1,3 +1,24 @@
2008-12-11 Tom Tromey <tromey@redhat.com>
PR macros/2564:
* c-exp.y (macro_original_text, expansion_obstack,
expression_macro_scope): New globals.
(scan_macro_expansion): New function.
(scanning_macro_expansion): Likewise.
(finished_macro_expansion): Likewise.
(scan_macro_cleanup): Likewise.
(c_parse): Find macro scope. Initialize obstack.
* c-lang.h (scan_macro_expansion, scanning_macro_expansion,
finished_macro_expansion, expression_macro_lookup_func,
expression_macro_lookup_baton): Remove.
* c-lang.c (scan_macro_expansion, scanning_macro_expansion,
finished_macro_expansion, expression_macro_lookup_func,
expression_macro_lookup_baton): Remove.
(macro_original_text, macro_expanded_text,
c_preprocess_and_parse): Remove.
(c_language_defn, cplus_language_defn, asm_language_defn,
minimal_language_defn): Use c_parse.
2008-12-10 Pedro Alves <pedro@codesourcery.com>
* infcmd.c (until_next_command, finish_backward): Use get_frame_pc

View File

@ -54,6 +54,8 @@ Boston, MA 02110-1301, USA. */
#include "block.h"
#include "cp-support.h"
#include "dfp.h"
#include "gdb_assert.h"
#include "macroscope.h"
#define parse_type builtin_type (parse_gdbarch)
@ -1396,6 +1398,85 @@ static const struct token tokentab2[] =
{">=", GEQ, BINOP_END}
};
/* When we find that lexptr (the global var defined in parse.c) is
pointing at a macro invocation, we expand the invocation, and call
scan_macro_expansion to save the old lexptr here and point lexptr
into the expanded text. When we reach the end of that, we call
end_macro_expansion to pop back to the value we saved here. The
macro expansion code promises to return only fully-expanded text,
so we don't need to "push" more than one level.
This is disgusting, of course. It would be cleaner to do all macro
expansion beforehand, and then hand that to lexptr. But we don't
really know where the expression ends. Remember, in a command like
(gdb) break *ADDRESS if CONDITION
we evaluate ADDRESS in the scope of the current frame, but we
evaluate CONDITION in the scope of the breakpoint's location. So
it's simply wrong to try to macro-expand the whole thing at once. */
static char *macro_original_text;
/* We save all intermediate macro expansions on this obstack for the
duration of a single parse. The expansion text may sometimes have
to live past the end of the expansion, due to yacc lookahead.
Rather than try to be clever about saving the data for a single
token, we simply keep it all and delete it after parsing has
completed. */
static struct obstack expansion_obstack;
static void
scan_macro_expansion (char *expansion)
{
char *copy;
/* We'd better not be trying to push the stack twice. */
gdb_assert (! macro_original_text);
/* Copy to the obstack, and then free the intermediate
expansion. */
copy = obstack_copy0 (&expansion_obstack, expansion, strlen (expansion));
xfree (expansion);
/* Save the old lexptr value, so we can return to it when we're done
parsing the expanded text. */
macro_original_text = lexptr;
lexptr = copy;
}
static int
scanning_macro_expansion (void)
{
return macro_original_text != 0;
}
static void
finished_macro_expansion (void)
{
/* There'd better be something to pop back to. */
gdb_assert (macro_original_text);
/* Pop back to the original text. */
lexptr = macro_original_text;
macro_original_text = 0;
}
static void
scan_macro_cleanup (void *dummy)
{
if (macro_original_text)
finished_macro_expansion ();
obstack_free (&expansion_obstack, NULL);
}
/* The scope used for macro expansion. */
static struct macro_scope *expression_macro_scope;
/* This is set if a NAME token appeared at the very end of the input
string, with no whitespace separating the name from the EOF. This
is used only when parsing to do field name completion. */
@ -1431,8 +1512,8 @@ yylex ()
if (! scanning_macro_expansion ())
{
char *expanded = macro_expand_next (&lexptr,
expression_macro_lookup_func,
expression_macro_lookup_baton);
standard_macro_lookup,
expression_macro_scope);
if (expanded)
scan_macro_expansion (expanded);
@ -1903,11 +1984,36 @@ yylex ()
int
c_parse (void)
{
int result;
struct cleanup *back_to = make_cleanup (free_current_contents,
&expression_macro_scope);
/* Set up the scope for macro expansion. */
expression_macro_scope = NULL;
if (expression_context_block)
expression_macro_scope
= sal_macro_scope (find_pc_line (expression_context_pc, 0));
else
expression_macro_scope = default_macro_scope ();
if (! expression_macro_scope)
expression_macro_scope = user_macro_scope ();
/* Initialize macro expansion code. */
obstack_init (&expansion_obstack);
gdb_assert (! macro_original_text);
make_cleanup (scan_macro_cleanup, 0);
/* Initialize some state used by the lexer. */
last_was_structop = 0;
saw_name_at_eof = 0;
return yyparse ();
result = yyparse ();
do_cleanups (back_to);
return result;
}
void
yyerror (msg)
char *msg;

View File

@ -185,111 +185,6 @@ c_printstr (struct ui_file *stream, const gdb_byte *string,
/* Preprocessing and parsing C and C++ expressions. */
/* When we find that lexptr (the global var defined in parse.c) is
pointing at a macro invocation, we expand the invocation, and call
scan_macro_expansion to save the old lexptr here and point lexptr
into the expanded text. When we reach the end of that, we call
end_macro_expansion to pop back to the value we saved here. The
macro expansion code promises to return only fully-expanded text,
so we don't need to "push" more than one level.
This is disgusting, of course. It would be cleaner to do all macro
expansion beforehand, and then hand that to lexptr. But we don't
really know where the expression ends. Remember, in a command like
(gdb) break *ADDRESS if CONDITION
we evaluate ADDRESS in the scope of the current frame, but we
evaluate CONDITION in the scope of the breakpoint's location. So
it's simply wrong to try to macro-expand the whole thing at once. */
static char *macro_original_text;
static char *macro_expanded_text;
void
scan_macro_expansion (char *expansion)
{
/* We'd better not be trying to push the stack twice. */
gdb_assert (! macro_original_text);
gdb_assert (! macro_expanded_text);
/* Save the old lexptr value, so we can return to it when we're done
parsing the expanded text. */
macro_original_text = lexptr;
lexptr = expansion;
/* Save the expanded text, so we can free it when we're finished. */
macro_expanded_text = expansion;
}
int
scanning_macro_expansion (void)
{
return macro_original_text != 0;
}
void
finished_macro_expansion (void)
{
/* There'd better be something to pop back to, and we better have
saved a pointer to the start of the expanded text. */
gdb_assert (macro_original_text);
gdb_assert (macro_expanded_text);
/* Pop back to the original text. */
lexptr = macro_original_text;
macro_original_text = 0;
/* Free the expanded text. */
xfree (macro_expanded_text);
macro_expanded_text = 0;
}
static void
scan_macro_cleanup (void *dummy)
{
if (macro_original_text)
finished_macro_expansion ();
}
/* We set these global variables before calling c_parse, to tell it
how it to find macro definitions for the expression at hand. */
macro_lookup_ftype *expression_macro_lookup_func;
void *expression_macro_lookup_baton;
static int
c_preprocess_and_parse (void)
{
/* Set up a lookup function for the macro expander. */
struct macro_scope *scope = 0;
struct cleanup *back_to = make_cleanup (free_current_contents, &scope);
if (expression_context_block)
scope = sal_macro_scope (find_pc_line (expression_context_pc, 0));
else
scope = default_macro_scope ();
if (! scope)
scope = user_macro_scope ();
expression_macro_lookup_func = standard_macro_lookup;
expression_macro_lookup_baton = (void *) scope;
gdb_assert (! macro_original_text);
make_cleanup (scan_macro_cleanup, 0);
{
int result = c_parse ();
do_cleanups (back_to);
return result;
}
}
/* Table mapping opcodes into strings for printing operators
and precedences of the operators. */
@ -395,7 +290,7 @@ const struct language_defn c_language_defn =
array_row_major,
macro_expansion_c,
&exp_descriptor_standard,
c_preprocess_and_parse,
c_parse,
c_error,
null_post_parser,
c_printchar, /* Print a character constant */
@ -513,7 +408,7 @@ const struct language_defn cplus_language_defn =
array_row_major,
macro_expansion_c,
&exp_descriptor_standard,
c_preprocess_and_parse,
c_parse,
c_error,
null_post_parser,
c_printchar, /* Print a character constant */
@ -550,7 +445,7 @@ const struct language_defn asm_language_defn =
array_row_major,
macro_expansion_c,
&exp_descriptor_standard,
c_preprocess_and_parse,
c_parse,
c_error,
null_post_parser,
c_printchar, /* Print a character constant */
@ -592,7 +487,7 @@ const struct language_defn minimal_language_defn =
array_row_major,
macro_expansion_c,
&exp_descriptor_standard,
c_preprocess_and_parse,
c_parse,
c_error,
null_post_parser,
c_printchar, /* Print a character constant */

View File

@ -55,13 +55,6 @@ extern void c_printstr (struct ui_file * stream, const gdb_byte *string,
int force_ellipses,
const struct value_print_options *options);
extern void scan_macro_expansion (char *expansion);
extern int scanning_macro_expansion (void);
extern void finished_macro_expansion (void);
extern macro_lookup_ftype *expression_macro_lookup_func;
extern void *expression_macro_lookup_baton;
extern void c_language_arch_info (struct gdbarch *gdbarch,
struct language_arch_info *lai);

View File

@ -1,3 +1,9 @@
2008-12-11 Tom Tromey <tromey@redhat.com>
* gdb.base/macscp.exp: Print "address.addr".
* gdb.base/macscp1.c (struct outer): New struct.
(address): New global.
2008-12-09 Tom Tromey <tromey@redhat.com>
* gdb.base/commands.exp (redefine_backtrace_test): New proc.

View File

@ -415,6 +415,10 @@ gdb_test "break [gdb_get_line_number "set breakpoint here"]" \
gdb_test "continue" "foo = 0;.*" "continue to macsp_expr"
gdb_test "print address.addr" \
" = 0" \
"print address.addr"
gdb_test "print MACRO_TO_EXPAND" \
"No symbol \"MACRO_TO_EXPAND\" in current context\." \
"print expression with macro before define."

View File

@ -10,6 +10,20 @@
#define FORTY_EIGHT 48
#undef FORTY_EIGHT
struct outer
{
struct fields
{
struct fault
{
int addr;
} fault;
} fields;
};
struct outer address;
#define addr fields.fault.addr
/* A macro named UNTIL_<func> is #defined until just before the
definition of the function <func>.