PR macros/13205:

* macrotab.h: (macro_define_special): Declare.
	(enum macro_special_kind): New.
	(struct macro_definition) <argc, replacement>: Update comments.
	* macrotab.c (new_macro_definition): Unconditionally set 'argc'.
	(macro_define_object_internal): New function.
	(macro_define_object): Use it.
	(macro_define_special): New function.
	(fixup_definition): New function.
	(macro_lookup_definition, foreach_macro_in_scope)
	(foreach_macro): Use fixup_definition.
	* macroexp.h (macro_stringify): Declare.
	* macroexp.c (free_buffer_return_text): New function.
	(stringify): Constify "arg".
	(macro_stringify): New function.
	* dwarf2read.c (macro_start_file): Call macro_define_special.
testsuite
	* gdb.base/macscp1.c (macscp_expr): Add comment.
	* gdb.base/macscp.exp: Test __FILE__ and __LINE__.
This commit is contained in:
Tom Tromey 2012-05-16 20:31:10 +00:00
parent 7537bd464b
commit abc9d0dc6e
9 changed files with 160 additions and 18 deletions

View file

@ -1,3 +1,22 @@
2012-05-16 Tom Tromey <tromey@redhat.com>
PR macros/13205:
* macrotab.h: (macro_define_special): Declare.
(enum macro_special_kind): New.
(struct macro_definition) <argc, replacement>: Update comments.
* macrotab.c (new_macro_definition): Unconditionally set 'argc'.
(macro_define_object_internal): New function.
(macro_define_object): Use it.
(macro_define_special): New function.
(fixup_definition): New function.
(macro_lookup_definition, foreach_macro_in_scope)
(foreach_macro): Use fixup_definition.
* macroexp.h (macro_stringify): Declare.
* macroexp.c (free_buffer_return_text): New function.
(stringify): Constify "arg".
(macro_stringify): New function.
* dwarf2read.c (macro_start_file): Call macro_define_special.
2012-05-16 Maciej W. Rozycki <macro@codesourcery.com> 2012-05-16 Maciej W. Rozycki <macro@codesourcery.com>
Maciej W. Rozycki <macro@mips.com> Maciej W. Rozycki <macro@mips.com>

View file

@ -15572,9 +15572,12 @@ macro_start_file (int file, int line,
objfile->macro_cache); objfile->macro_cache);
if (! current_file) if (! current_file)
/* If we have no current file, then this must be the start_file {
directive for the compilation unit's main source file. */ /* If we have no current file, then this must be the start_file
current_file = macro_set_main (pending_macros, full_name); directive for the compilation unit's main source file. */
current_file = macro_set_main (pending_macros, full_name);
macro_define_special (pending_macros);
}
else else
current_file = macro_include (current_file, line, full_name); current_file = macro_include (current_file, line, full_name);

View file

@ -113,6 +113,17 @@ free_buffer (struct macro_buffer *b)
xfree (b->text); xfree (b->text);
} }
/* Like free_buffer, but return the text as an xstrdup()d string.
This only exists to try to make the API relatively clean. */
static char *
free_buffer_return_text (struct macro_buffer *b)
{
gdb_assert (! b->shared);
gdb_assert (b->size);
/* Nothing to do. */
return b->text;
}
/* A cleanup function for macro buffers. */ /* A cleanup function for macro buffers. */
static void static void
@ -639,7 +650,7 @@ append_tokens_without_splicing (struct macro_buffer *dest,
stringify; it is LEN bytes long. */ stringify; it is LEN bytes long. */
static void static void
stringify (struct macro_buffer *dest, char *arg, int len) stringify (struct macro_buffer *dest, const char *arg, int len)
{ {
/* Trim initial whitespace from ARG. */ /* Trim initial whitespace from ARG. */
while (len > 0 && macro_is_whitespace (*arg)) while (len > 0 && macro_is_whitespace (*arg))
@ -682,6 +693,21 @@ stringify (struct macro_buffer *dest, char *arg, int len)
dest->last_token = dest->len; dest->last_token = dest->len;
} }
/* See macroexp.h. */
char *
macro_stringify (const char *str)
{
struct macro_buffer buffer;
int len = strlen (str);
char *result;
init_buffer (&buffer, len);
stringify (&buffer, str, len);
return free_buffer_return_text (&buffer);
}
/* Expanding macros! */ /* Expanding macros! */

View file

@ -91,4 +91,9 @@ int macro_is_identifier_nondigit (int c);
int macro_is_digit (int c); int macro_is_digit (int c);
/* Stringify STR according to C rules and return an xmalloc'd pointer
to the result. */
char *macro_stringify (const char *str);
#endif /* MACROEXP_H */ #endif /* MACROEXP_H */

View file

@ -28,6 +28,7 @@
#include "gdb_assert.h" #include "gdb_assert.h"
#include "bcache.h" #include "bcache.h"
#include "complaints.h" #include "complaints.h"
#include "macroexp.h"
/* The macro table structure. */ /* The macro table structure. */
@ -565,6 +566,7 @@ new_macro_definition (struct macro_table *t,
d->table = t; d->table = t;
d->kind = kind; d->kind = kind;
d->replacement = macro_bcache_str (t, replacement); d->replacement = macro_bcache_str (t, replacement);
d->argc = argc;
if (kind == macro_function_like) if (kind == macro_function_like)
{ {
@ -579,7 +581,6 @@ new_macro_definition (struct macro_table *t,
/* Now bcache the array of argument pointers itself. */ /* Now bcache the array of argument pointers itself. */
d->argv = macro_bcache (t, cached_argv, cached_argv_size); d->argv = macro_bcache (t, cached_argv, cached_argv_size);
d->argc = argc;
} }
/* We don't bcache the entire definition structure because it's got /* We don't bcache the entire definition structure because it's got
@ -742,10 +743,12 @@ check_for_redefinition (struct macro_source_file *source, int line,
return 0; return 0;
} }
/* A helper function to define a new object-like macro. */
void static void
macro_define_object (struct macro_source_file *source, int line, macro_define_object_internal (struct macro_source_file *source, int line,
const char *name, const char *replacement) const char *name, const char *replacement,
enum macro_special_kind kind)
{ {
struct macro_table *t = source->table; struct macro_table *t = source->table;
struct macro_key *k = NULL; struct macro_key *k = NULL;
@ -771,10 +774,28 @@ macro_define_object (struct macro_source_file *source, int line,
return; return;
k = new_macro_key (t, name, source, line); k = new_macro_key (t, name, source, line);
d = new_macro_definition (t, macro_object_like, 0, 0, replacement); d = new_macro_definition (t, macro_object_like, kind, 0, replacement);
splay_tree_insert (t->definitions, (splay_tree_key) k, (splay_tree_value) d); splay_tree_insert (t->definitions, (splay_tree_key) k, (splay_tree_value) d);
} }
void
macro_define_object (struct macro_source_file *source, int line,
const char *name, const char *replacement)
{
macro_define_object_internal (source, line, name, replacement,
macro_ordinary);
}
/* See macrotab.h. */
void
macro_define_special (struct macro_table *table)
{
macro_define_object_internal (table->main_source, -1, "__FILE__", "",
macro_FILE);
macro_define_object_internal (table->main_source, -1, "__LINE__", "",
macro_LINE);
}
void void
macro_define_function (struct macro_source_file *source, int line, macro_define_function (struct macro_source_file *source, int line,
@ -859,6 +880,36 @@ macro_undef (struct macro_source_file *source, int line,
} }
} }
/* A helper function that rewrites the definition of a special macro,
when needed. */
static struct macro_definition *
fixup_definition (const char *filename, int line, struct macro_definition *def)
{
static char *saved_expansion;
if (saved_expansion)
{
xfree (saved_expansion);
saved_expansion = NULL;
}
if (def->kind == macro_object_like)
{
if (def->argc == macro_FILE)
{
saved_expansion = macro_stringify (filename);
def->replacement = saved_expansion;
}
else if (def->argc == macro_LINE)
{
saved_expansion = xstrprintf ("%d", line);
def->replacement = saved_expansion;
}
}
return def;
}
struct macro_definition * struct macro_definition *
macro_lookup_definition (struct macro_source_file *source, macro_lookup_definition (struct macro_source_file *source,
@ -867,7 +918,8 @@ macro_lookup_definition (struct macro_source_file *source,
splay_tree_node n = find_definition (name, source, line); splay_tree_node n = find_definition (name, source, line);
if (n) if (n)
return (struct macro_definition *) n->value; return fixup_definition (source->filename, line,
(struct macro_definition *) n->value);
else else
return 0; return 0;
} }
@ -910,7 +962,9 @@ foreach_macro (splay_tree_node node, void *arg)
{ {
struct macro_for_each_data *datum = (struct macro_for_each_data *) arg; struct macro_for_each_data *datum = (struct macro_for_each_data *) arg;
struct macro_key *key = (struct macro_key *) node->key; struct macro_key *key = (struct macro_key *) node->key;
struct macro_definition *def = (struct macro_definition *) node->value; struct macro_definition *def
= fixup_definition (key->start_file->filename, key->start_line,
(struct macro_definition *) node->value);
(*datum->fn) (key->name, def, key->start_file, key->start_line, (*datum->fn) (key->name, def, key->start_file, key->start_line,
datum->user_data); datum->user_data);
@ -936,7 +990,9 @@ foreach_macro_in_scope (splay_tree_node node, void *info)
{ {
struct macro_for_each_data *datum = (struct macro_for_each_data *) info; struct macro_for_each_data *datum = (struct macro_for_each_data *) info;
struct macro_key *key = (struct macro_key *) node->key; struct macro_key *key = (struct macro_key *) node->key;
struct macro_definition *def = (struct macro_definition *) node->value; struct macro_definition *def
= fixup_definition (datum->file->filename, datum->line,
(struct macro_definition *) node->value);
/* See if this macro is defined before the passed-in line, and /* See if this macro is defined before the passed-in line, and
extends past that line. */ extends past that line. */

View file

@ -212,6 +212,10 @@ struct macro_source_file *macro_include (struct macro_source_file *source,
int line, int line,
const char *included); const char *included);
/* Define any special macros, like __FILE__ or __LINE__. This should
be called once, on the main source file. */
void macro_define_special (struct macro_table *table);
/* Find any source file structure for a file named NAME, either /* Find any source file structure for a file named NAME, either
included into SOURCE, or SOURCE itself. Return zero if we have included into SOURCE, or SOURCE itself. Return zero if we have
@ -261,6 +265,17 @@ enum macro_kind
macro_function_like macro_function_like
}; };
/* Different kinds of special macros. */
enum macro_special_kind
{
/* Ordinary. */
macro_ordinary,
/* The special macro __FILE__. */
macro_FILE,
/* The special macro __LINE__. */
macro_LINE
};
/* A preprocessor symbol definition. */ /* A preprocessor symbol definition. */
struct macro_definition struct macro_definition
@ -273,12 +288,17 @@ struct macro_definition
/* If `kind' is `macro_function_like', the number of arguments it /* If `kind' is `macro_function_like', the number of arguments it
takes, and their names. The names, and the array of pointers to takes, and their names. The names, and the array of pointers to
them, are in the table's bcache, if it has one. */ them, are in the table's bcache, if it has one. If `kind' is
int argc : 31; `macro_object_like', then this is actually a `macro_special_kind'
describing the macro. */
int argc : 30;
const char * const *argv; const char * const *argv;
/* The replacement string (body) of the macro. This is in the /* The replacement string (body) of the macro. For ordinary macros,
table's bcache, if it has one. */ this is in the table's bcache, if it has one. For special macros
like __FILE__, this value is only valid until the next use of any
special macro definition; that is, it is reset each time any
special macro is looked up or iterated over. */
const char *replacement; const char *replacement;
}; };

View file

@ -1,3 +1,8 @@
2012-05-16 Tom Tromey <tromey@redhat.com>
* gdb.base/macscp1.c (macscp_expr): Add comment.
* gdb.base/macscp.exp: Test __FILE__ and __LINE__.
2012-05-16 Maciej W. Rozycki <macro@codesourcery.com> 2012-05-16 Maciej W. Rozycki <macro@codesourcery.com>
* gdb.base/return-nodebug.exp: Also test float and double types. * gdb.base/return-nodebug.exp: Also test float and double types.

View file

@ -227,6 +227,10 @@ list_and_check_macro macscp3_2 WHERE {macscp3.h macscp1.c {before macscp3_2}}
gdb_test "info macro FROM_COMMANDLINE" \ gdb_test "info macro FROM_COMMANDLINE" \
"Defined at \[^\r\n\]*:0\r\n-DFROM_COMMANDLINE=ARG" "Defined at \[^\r\n\]*:0\r\n-DFROM_COMMANDLINE=ARG"
gdb_test "info macro __FILE__" "#define __FILE__ \".*macscp3.h\"" \
"info macro __FILE__ before running"
gdb_test "info macro __LINE__" "#define __LINE__ 26" \
"info macro __LINE__ before running"
# Although GDB's macro table structures distinguish between multiple # Although GDB's macro table structures distinguish between multiple
# #inclusions of the same file, GDB's other structures don't. So the # #inclusions of the same file, GDB's other structures don't. So the
@ -466,7 +470,7 @@ gdb_test "print MACRO_TO_EXPAND" \
" = 0" \ " = 0" \
"print expression with macro after removing override" "print expression with macro after removing override"
gdb_test "next" "foo = 2;" "next to definition 2" gdb_test "next" "foo = 2;.*" "next to definition 2"
gdb_test "print MACRO_TO_EXPAND" \ gdb_test "print MACRO_TO_EXPAND" \
"No symbol \"MACRO_TO_EXPAND\" in current context\." \ "No symbol \"MACRO_TO_EXPAND\" in current context\." \
@ -673,3 +677,7 @@ gdb_test_no_output "macro define si_addr fields.fault.si_addr" \
gdb_test "macro expand siginfo.si_addr" \ gdb_test "macro expand siginfo.si_addr" \
"expands to: siginfo.fields.fault.si_addr" \ "expands to: siginfo.fields.fault.si_addr" \
"macro expand siginfo.si_addr" "macro expand siginfo.si_addr"
gdb_test "print __FILE__" " = \".*macscp1.c\""
gdb_test "print __LINE__" \
" = [gdb_get_line_number {stopping point for line test}]"

View file

@ -91,7 +91,7 @@ macscp_expr (void)
#define MACRO_TO_EXPAND foo #define MACRO_TO_EXPAND foo
foo = 1; foo = 1;
#undef MACRO_TO_EXPAND #undef MACRO_TO_EXPAND
foo = 2; foo = 2; /* stopping point for line test */
} }
#define TWENTY_THREE 23 #define TWENTY_THREE 23