gdb
PR gdb/2484: * symtab.c (struct add_macro_name_data): New struct. (add_macro_name): New function. (default_make_symbol_completion_list): Complete macro names. * scm-lang.c (scm_language_defn): Update. * p-lang.c (pascal_language_defn): Update. * objc-lang.c (objc_language_defn): Update. * macrotab.h (macro_callback_fn): Add user_data argument. (macro_for_each): Likewise. (macro_for_each_in_scope): Declare. * macrotab.c: (struct macro_for_each_data): New struct. (foreach_macro): Use it. (macro_for_each): Likewise. (foreach_macro_in_scope): New function. (macro_for_each_in_scope): Likewise. * macrocmd.c (print_one_macro): Add argument. (macro_list_command): Pass NULL to macro_for_each. * m2-lang.c (m2_language_defn): Update. * language.h (struct language_defn) <la_macro_expansion>: New field. (macro_expansion): New enum. * language.c (unknown_language_defn): Update. Fix order of initializers. (auto_language_defn): Likewise. (local_language_defn): Update. * jv-lang.c (java_language_defn): Update. * f-lang.c (f_language_defn): Update. * c-lang.c (c_language_defn): Update. (cplus_language_defn): Likewise. (asm_language_defn): Likewise. (minimal_language_defn): Likewise. * ada-lang.c (ada_language_defn): Update. gdb/testsuite * gdb.base/macscp.exp: Add completion tests. * gdb.base/macscp1.c (FIFTY_SEVEN): New macro. (TWENTY_THREE): Likewise. (FORTY_EIGHT): Likewise.
This commit is contained in:
parent
b084d49989
commit
9a044a8903
18 changed files with 276 additions and 16 deletions
|
@ -1,3 +1,38 @@
|
|||
2008-09-30 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR gdb/2484:
|
||||
* symtab.c (struct add_macro_name_data): New struct.
|
||||
(add_macro_name): New function.
|
||||
(default_make_symbol_completion_list): Complete macro names.
|
||||
* scm-lang.c (scm_language_defn): Update.
|
||||
* p-lang.c (pascal_language_defn): Update.
|
||||
* objc-lang.c (objc_language_defn): Update.
|
||||
* macrotab.h (macro_callback_fn): Add user_data argument.
|
||||
(macro_for_each): Likewise.
|
||||
(macro_for_each_in_scope): Declare.
|
||||
* macrotab.c: (struct macro_for_each_data): New struct.
|
||||
(foreach_macro): Use it.
|
||||
(macro_for_each): Likewise.
|
||||
(foreach_macro_in_scope): New function.
|
||||
(macro_for_each_in_scope): Likewise.
|
||||
* macrocmd.c (print_one_macro): Add argument.
|
||||
(macro_list_command): Pass NULL to macro_for_each.
|
||||
* m2-lang.c (m2_language_defn): Update.
|
||||
* language.h (struct language_defn) <la_macro_expansion>: New
|
||||
field.
|
||||
(macro_expansion): New enum.
|
||||
* language.c (unknown_language_defn): Update. Fix order of
|
||||
initializers.
|
||||
(auto_language_defn): Likewise.
|
||||
(local_language_defn): Update.
|
||||
* jv-lang.c (java_language_defn): Update.
|
||||
* f-lang.c (f_language_defn): Update.
|
||||
* c-lang.c (c_language_defn): Update.
|
||||
(cplus_language_defn): Likewise.
|
||||
(asm_language_defn): Likewise.
|
||||
(minimal_language_defn): Likewise.
|
||||
* ada-lang.c (ada_language_defn): Update.
|
||||
|
||||
2008-09-30 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* dwarf2read.c (dwarf2_get_subprogram_pc_bounds): New function.
|
||||
|
|
|
@ -10935,6 +10935,7 @@ const struct language_defn ada_language_defn = {
|
|||
case_sensitive_on, /* Yes, Ada is case-insensitive, but
|
||||
that's not quite what this means. */
|
||||
array_row_major,
|
||||
macro_expansion_no,
|
||||
&ada_exp_descriptor,
|
||||
parse,
|
||||
ada_error,
|
||||
|
|
|
@ -392,6 +392,7 @@ const struct language_defn c_language_defn =
|
|||
type_check_off,
|
||||
case_sensitive_on,
|
||||
array_row_major,
|
||||
macro_expansion_c,
|
||||
&exp_descriptor_standard,
|
||||
c_preprocess_and_parse,
|
||||
c_error,
|
||||
|
@ -509,6 +510,7 @@ const struct language_defn cplus_language_defn =
|
|||
type_check_off,
|
||||
case_sensitive_on,
|
||||
array_row_major,
|
||||
macro_expansion_c,
|
||||
&exp_descriptor_standard,
|
||||
c_preprocess_and_parse,
|
||||
c_error,
|
||||
|
@ -545,6 +547,7 @@ const struct language_defn asm_language_defn =
|
|||
type_check_off,
|
||||
case_sensitive_on,
|
||||
array_row_major,
|
||||
macro_expansion_c,
|
||||
&exp_descriptor_standard,
|
||||
c_preprocess_and_parse,
|
||||
c_error,
|
||||
|
@ -586,6 +589,7 @@ const struct language_defn minimal_language_defn =
|
|||
type_check_off,
|
||||
case_sensitive_on,
|
||||
array_row_major,
|
||||
macro_expansion_c,
|
||||
&exp_descriptor_standard,
|
||||
c_preprocess_and_parse,
|
||||
c_error,
|
||||
|
|
|
@ -316,6 +316,7 @@ const struct language_defn f_language_defn =
|
|||
type_check_on,
|
||||
case_sensitive_off,
|
||||
array_column_major,
|
||||
macro_expansion_no,
|
||||
&exp_descriptor_standard,
|
||||
f_parse, /* parser */
|
||||
f_error, /* parser error function */
|
||||
|
|
|
@ -1102,6 +1102,7 @@ const struct language_defn java_language_defn =
|
|||
type_check_off,
|
||||
case_sensitive_on,
|
||||
array_row_major,
|
||||
macro_expansion_no,
|
||||
&exp_descriptor_java,
|
||||
java_parse,
|
||||
java_error,
|
||||
|
|
|
@ -1135,8 +1135,9 @@ const struct language_defn unknown_language_defn =
|
|||
language_unknown,
|
||||
range_check_off,
|
||||
type_check_off,
|
||||
array_row_major,
|
||||
case_sensitive_on,
|
||||
array_row_major,
|
||||
macro_expansion_no,
|
||||
&exp_descriptor_standard,
|
||||
unk_lang_parser,
|
||||
unk_lang_error,
|
||||
|
@ -1172,8 +1173,9 @@ const struct language_defn auto_language_defn =
|
|||
language_auto,
|
||||
range_check_off,
|
||||
type_check_off,
|
||||
array_row_major,
|
||||
case_sensitive_on,
|
||||
array_row_major,
|
||||
macro_expansion_no,
|
||||
&exp_descriptor_standard,
|
||||
unk_lang_parser,
|
||||
unk_lang_error,
|
||||
|
@ -1210,6 +1212,7 @@ const struct language_defn local_language_defn =
|
|||
type_check_off,
|
||||
case_sensitive_on,
|
||||
array_row_major,
|
||||
macro_expansion_no,
|
||||
&exp_descriptor_standard,
|
||||
unk_lang_parser,
|
||||
unk_lang_error,
|
||||
|
|
|
@ -105,6 +105,17 @@ extern enum case_sensitivity
|
|||
case_sensitive_on, case_sensitive_off
|
||||
}
|
||||
case_sensitivity;
|
||||
|
||||
|
||||
/* macro_expansion ==
|
||||
macro_expansion_no: No macro expansion is available
|
||||
macro_expansion_c: C-like macro expansion is available */
|
||||
|
||||
enum macro_expansion
|
||||
{
|
||||
macro_expansion_no, macro_expansion_c
|
||||
};
|
||||
|
||||
|
||||
/* Per architecture (OS/ABI) language information. */
|
||||
|
||||
|
@ -150,6 +161,9 @@ struct language_defn
|
|||
/* Multi-dimensional array ordering */
|
||||
enum array_ordering la_array_ordering;
|
||||
|
||||
/* Style of macro expansion, if any, supported by this language. */
|
||||
enum macro_expansion la_macro_expansion;
|
||||
|
||||
/* Definitions related to expression printing, prefixifying, and
|
||||
dumping */
|
||||
|
||||
|
|
|
@ -367,6 +367,7 @@ const struct language_defn m2_language_defn =
|
|||
type_check_on,
|
||||
case_sensitive_on,
|
||||
array_row_major,
|
||||
macro_expansion_no,
|
||||
&exp_descriptor_modula2,
|
||||
m2_parse, /* parser */
|
||||
m2_error, /* parser error function */
|
||||
|
|
|
@ -345,7 +345,8 @@ macro_undef_command (char *exp, int from_tty)
|
|||
|
||||
|
||||
static void
|
||||
print_one_macro (const char *name, const struct macro_definition *macro)
|
||||
print_one_macro (const char *name, const struct macro_definition *macro,
|
||||
void *ignore)
|
||||
{
|
||||
fprintf_filtered (gdb_stdout, "macro define %s", name);
|
||||
if (macro->kind == macro_function_like)
|
||||
|
@ -366,7 +367,7 @@ print_one_macro (const char *name, const struct macro_definition *macro)
|
|||
static void
|
||||
macro_list_command (char *exp, int from_tty)
|
||||
{
|
||||
macro_for_each (macro_user_macros, print_one_macro);
|
||||
macro_for_each (macro_user_macros, print_one_macro, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -887,25 +887,71 @@ macro_definition_location (struct macro_source_file *source,
|
|||
}
|
||||
|
||||
|
||||
/* The type for callback data for iterating the splay tree in
|
||||
macro_for_each and macro_for_each_in_scope. Only the latter uses
|
||||
the FILE and LINE fields. */
|
||||
struct macro_for_each_data
|
||||
{
|
||||
macro_callback_fn fn;
|
||||
void *user_data;
|
||||
struct macro_source_file *file;
|
||||
int line;
|
||||
};
|
||||
|
||||
/* Helper function for macro_for_each. */
|
||||
static int
|
||||
foreach_macro (splay_tree_node node, void *fnp)
|
||||
foreach_macro (splay_tree_node node, void *arg)
|
||||
{
|
||||
macro_callback_fn *fn = (macro_callback_fn *) fnp;
|
||||
struct macro_for_each_data *datum = (struct macro_for_each_data *) arg;
|
||||
struct macro_key *key = (struct macro_key *) node->key;
|
||||
struct macro_definition *def = (struct macro_definition *) node->value;
|
||||
(**fn) (key->name, def);
|
||||
(*datum->fn) (key->name, def, datum->user_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Call FN for every macro in TABLE. */
|
||||
void
|
||||
macro_for_each (struct macro_table *table, macro_callback_fn fn)
|
||||
macro_for_each (struct macro_table *table, macro_callback_fn fn,
|
||||
void *user_data)
|
||||
{
|
||||
/* Note that we pass in the address of 'fn' because, pedantically
|
||||
speaking, we can't necessarily cast a pointer-to-function to a
|
||||
void*. */
|
||||
splay_tree_foreach (table->definitions, foreach_macro, &fn);
|
||||
struct macro_for_each_data datum;
|
||||
datum.fn = fn;
|
||||
datum.user_data = user_data;
|
||||
datum.file = NULL;
|
||||
datum.line = 0;
|
||||
splay_tree_foreach (table->definitions, foreach_macro, &datum);
|
||||
}
|
||||
|
||||
static int
|
||||
foreach_macro_in_scope (splay_tree_node node, void *info)
|
||||
{
|
||||
struct macro_for_each_data *datum = (struct macro_for_each_data *) info;
|
||||
struct macro_key *key = (struct macro_key *) node->key;
|
||||
struct macro_definition *def = (struct macro_definition *) node->value;
|
||||
|
||||
/* See if this macro is defined before the passed-in line, and
|
||||
extends past that line. */
|
||||
if (compare_locations (key->start_file, key->start_line,
|
||||
datum->file, datum->line) < 0
|
||||
&& (!key->end_file
|
||||
|| compare_locations (key->end_file, key->end_line,
|
||||
datum->file, datum->line) >= 0))
|
||||
(*datum->fn) (key->name, def, datum->user_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Call FN for every macro is visible in SCOPE. */
|
||||
void
|
||||
macro_for_each_in_scope (struct macro_source_file *file, int line,
|
||||
macro_callback_fn fn, void *user_data)
|
||||
{
|
||||
struct macro_for_each_data datum;
|
||||
datum.fn = fn;
|
||||
datum.user_data = user_data;
|
||||
datum.file = file;
|
||||
datum.line = line;
|
||||
splay_tree_foreach (file->table->definitions,
|
||||
foreach_macro_in_scope, &datum);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -305,12 +305,24 @@ struct macro_source_file *(macro_definition_location
|
|||
int *definition_line));
|
||||
|
||||
/* Callback function when walking a macro table. NAME is the name of
|
||||
the macro, and DEFINITION is the definition. */
|
||||
the macro, and DEFINITION is the definition. USER_DATA is an
|
||||
arbitrary pointer which is passed by the caller to macro_for_each
|
||||
or macro_for_each_in_scope. */
|
||||
typedef void (*macro_callback_fn) (const char *name,
|
||||
const struct macro_definition *definition);
|
||||
const struct macro_definition *definition,
|
||||
void *user_data);
|
||||
|
||||
/* Call the function FN for each macro in the macro table TABLE. */
|
||||
void macro_for_each (struct macro_table *table, macro_callback_fn fn);
|
||||
/* Call the function FN for each macro in the macro table TABLE.
|
||||
USER_DATA is passed, untranslated, to FN. */
|
||||
void macro_for_each (struct macro_table *table, macro_callback_fn fn,
|
||||
void *user_data);
|
||||
|
||||
/* Call the function FN for each macro that is visible in a given
|
||||
scope. The scope is represented by FILE and LINE. USER_DATA is
|
||||
passed, untranslated, to FN. */
|
||||
void macro_for_each_in_scope (struct macro_source_file *file, int line,
|
||||
macro_callback_fn fn,
|
||||
void *user_data);
|
||||
|
||||
|
||||
#endif /* MACROTAB_H */
|
||||
|
|
|
@ -504,6 +504,7 @@ const struct language_defn objc_language_defn = {
|
|||
type_check_off,
|
||||
case_sensitive_on,
|
||||
array_row_major,
|
||||
macro_expansion_c,
|
||||
&exp_descriptor_standard,
|
||||
objc_parse,
|
||||
objc_error,
|
||||
|
|
|
@ -406,6 +406,7 @@ const struct language_defn pascal_language_defn =
|
|||
type_check_on,
|
||||
case_sensitive_on,
|
||||
array_row_major,
|
||||
macro_expansion_no,
|
||||
&exp_descriptor_standard,
|
||||
pascal_parse,
|
||||
pascal_error,
|
||||
|
|
|
@ -246,6 +246,7 @@ const struct language_defn scm_language_defn =
|
|||
type_check_off,
|
||||
case_sensitive_off,
|
||||
array_row_major,
|
||||
macro_expansion_no,
|
||||
&exp_descriptor_scm,
|
||||
scm_parse,
|
||||
c_error,
|
||||
|
|
54
gdb/symtab.c
54
gdb/symtab.c
|
@ -58,6 +58,8 @@
|
|||
#include "observer.h"
|
||||
#include "gdb_assert.h"
|
||||
#include "solist.h"
|
||||
#include "macrotab.h"
|
||||
#include "macroscope.h"
|
||||
|
||||
/* Prototypes for local functions */
|
||||
|
||||
|
@ -3640,6 +3642,29 @@ language_search_unquoted_string (char *text, char *p)
|
|||
return p;
|
||||
}
|
||||
|
||||
/* Type of the user_data argument passed to add_macro_name. The
|
||||
contents are simply whatever is needed by
|
||||
completion_list_add_name. */
|
||||
struct add_macro_name_data
|
||||
{
|
||||
char *sym_text;
|
||||
int sym_text_len;
|
||||
char *text;
|
||||
char *word;
|
||||
};
|
||||
|
||||
/* A callback used with macro_for_each and macro_for_each_in_scope.
|
||||
This adds a macro's name to the current completion list. */
|
||||
static void
|
||||
add_macro_name (const char *name, const struct macro_definition *ignore,
|
||||
void *user_data)
|
||||
{
|
||||
struct add_macro_name_data *datum = (struct add_macro_name_data *) user_data;
|
||||
completion_list_add_name ((char *) name,
|
||||
datum->sym_text, datum->sym_text_len,
|
||||
datum->text, datum->word);
|
||||
}
|
||||
|
||||
char **
|
||||
default_make_symbol_completion_list (char *text, char *word)
|
||||
{
|
||||
|
@ -3826,6 +3851,35 @@ default_make_symbol_completion_list (char *text, char *word)
|
|||
}
|
||||
}
|
||||
|
||||
if (current_language->la_macro_expansion == macro_expansion_c)
|
||||
{
|
||||
struct macro_scope *scope;
|
||||
struct add_macro_name_data datum;
|
||||
|
||||
datum.sym_text = sym_text;
|
||||
datum.sym_text_len = sym_text_len;
|
||||
datum.text = text;
|
||||
datum.word = word;
|
||||
|
||||
/* Add any macros visible in the default scope. Note that this
|
||||
may yield the occasional wrong result, because an expression
|
||||
might be evaluated in a scope other than the default. For
|
||||
example, if the user types "break file:line if <TAB>", the
|
||||
resulting expression will be evaluated at "file:line" -- but
|
||||
at there does not seem to be a way to detect this at
|
||||
completion time. */
|
||||
scope = default_macro_scope ();
|
||||
if (scope)
|
||||
{
|
||||
macro_for_each_in_scope (scope->file, scope->line,
|
||||
add_macro_name, &datum);
|
||||
xfree (scope);
|
||||
}
|
||||
|
||||
/* User-defined macros are always visible. */
|
||||
macro_for_each (macro_user_macros, add_macro_name, &datum);
|
||||
}
|
||||
|
||||
return (return_val);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2008-09-30 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* gdb.base/macscp.exp: Add completion tests.
|
||||
* gdb.base/macscp1.c (FIFTY_SEVEN): New macro.
|
||||
(TWENTY_THREE): Likewise.
|
||||
(FORTY_EIGHT): Likewise.
|
||||
|
||||
2008-09-30 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* gdb.base/macscp.exp: Change "M" to "MACRO_TO_EXPAND"
|
||||
|
|
|
@ -480,6 +480,76 @@ gdb_test "macro undef" \
|
|||
"usage: macro undef.*" \
|
||||
"macro undef with no arguments"
|
||||
|
||||
# Completion tests.
|
||||
|
||||
# The macro FIFTY_SEVEN is in scope at this point.
|
||||
send_gdb "p FIFTY_\t"
|
||||
gdb_expect {
|
||||
-re "^p FIFTY_SEVEN $"\
|
||||
{ send_gdb "\n"
|
||||
gdb_expect {
|
||||
-re "^.* = 57.*$gdb_prompt $"\
|
||||
{ pass "complete 'p FIFTY_SEVEN'"}
|
||||
-re ".*$gdb_prompt $" { fail "complete 'p FIFTY_SEVEN'"}
|
||||
timeout {fail "(timeout) complete 'p FIFTY_SEVEN'"}
|
||||
}
|
||||
}
|
||||
-re ".*$gdb_prompt $" { fail "complete 'p FIFTY_SEVEN'" }
|
||||
timeout { fail "(timeout) complete 'p FIFTY_SEVEN' 2" }
|
||||
}
|
||||
|
||||
# The macro TWENTY_THREE is not in scope.
|
||||
send_gdb "p TWENTY_\t"
|
||||
gdb_expect {
|
||||
-re "^p TWENTY_\\\x07$"\
|
||||
{ send_gdb "\n"
|
||||
gdb_expect {
|
||||
-re "No symbol \"TWENTY_\" in current context\\..*$gdb_prompt $"\
|
||||
{ pass "complete 'p TWENTY_'"}
|
||||
-re ".*$gdb_prompt $" { fail "complete 'p TWENTY_'"}
|
||||
timeout {fail "(timeout) complete 'p TWENTY_'"}
|
||||
}
|
||||
}
|
||||
-re ".*$gdb_prompt $" { fail "complete 'p TWENTY_'" }
|
||||
timeout { fail "(timeout) complete 'p TWENTY_' 2" }
|
||||
}
|
||||
|
||||
# The macro FORTY_EIGHT was undefined and thus is not in scope.
|
||||
send_gdb "p FORTY_\t"
|
||||
gdb_expect {
|
||||
-re "^p FORTY_\\\x07$"\
|
||||
{ send_gdb "\n"
|
||||
gdb_expect {
|
||||
-re "No symbol \"FORTY_\" in current context\\..*$gdb_prompt $"\
|
||||
{ pass "complete 'p FORTY_'"}
|
||||
-re ".*$gdb_prompt $" { fail "complete 'p FORTY_'"}
|
||||
timeout {fail "(timeout) complete 'p FORTY_'"}
|
||||
}
|
||||
}
|
||||
-re ".*$gdb_prompt $" { fail "complete 'p FORTY_'" }
|
||||
timeout { fail "(timeout) complete 'p FORTY_' 2" }
|
||||
}
|
||||
|
||||
gdb_test "macro define TWENTY_THREE 25" \
|
||||
"" \
|
||||
"defining TWENTY_THREE"
|
||||
|
||||
# User-defined macros are always in scope.
|
||||
send_gdb "p TWENTY_\t"
|
||||
gdb_expect {
|
||||
-re "^p TWENTY_THREE $"\
|
||||
{ send_gdb "\n"
|
||||
gdb_expect {
|
||||
-re "^.* = 25.*$gdb_prompt $"\
|
||||
{ pass "complete 'p TWENTY_THREE'"}
|
||||
-re ".*$gdb_prompt $" { fail "complete 'p TWENTY_THREE'"}
|
||||
timeout {fail "(timeout) complete 'p TWENTY_THREE'"}
|
||||
}
|
||||
}
|
||||
-re ".*$gdb_prompt $" { fail "complete 'p TWENTY_THREE'" }
|
||||
timeout { fail "(timeout) complete 'p TWENTY_THREE' 2" }
|
||||
}
|
||||
|
||||
# Splicing tests.
|
||||
|
||||
gdb_test "macro expand SPLICE(x, y)" \
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
#define STRINGIFY(a) INNER_STRINGIFY(a)
|
||||
#define INNER_STRINGIFY(a) #a
|
||||
|
||||
#define FIFTY_SEVEN 57
|
||||
|
||||
#define FORTY_EIGHT 48
|
||||
#undef FORTY_EIGHT
|
||||
|
||||
/* A macro named UNTIL_<func> is #defined until just before the
|
||||
definition of the function <func>.
|
||||
|
||||
|
@ -75,6 +80,8 @@ macscp_expr (void)
|
|||
foo = 2;
|
||||
}
|
||||
|
||||
#define TWENTY_THREE 23
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue