aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog35
-rw-r--r--gdb/ada-lang.c1
-rw-r--r--gdb/c-lang.c4
-rw-r--r--gdb/f-lang.c1
-rw-r--r--gdb/jv-lang.c1
-rw-r--r--gdb/language.c7
-rw-r--r--gdb/language.h14
-rw-r--r--gdb/m2-lang.c1
-rw-r--r--gdb/macrocmd.c5
-rw-r--r--gdb/macrotab.c62
-rw-r--r--gdb/macrotab.h22
-rw-r--r--gdb/objc-lang.c1
-rw-r--r--gdb/p-lang.c1
-rw-r--r--gdb/scm-lang.c1
-rw-r--r--gdb/symtab.c54
-rw-r--r--gdb/testsuite/ChangeLog7
-rw-r--r--gdb/testsuite/gdb.base/macscp.exp70
-rw-r--r--gdb/testsuite/gdb.base/macscp1.c7
18 files changed, 277 insertions, 17 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index dfa6df1..6d33cbb 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index d4d7dc0..c425c80 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -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,
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index a9cd9c2..a978b17 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -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,
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 4e2f3c4..736d6c6 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -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 */
diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c
index 69570b4..0470eef 100644
--- a/gdb/jv-lang.c
+++ b/gdb/jv-lang.c
@@ -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,
diff --git a/gdb/language.c b/gdb/language.c
index 0b21dc3..121fc55 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -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,
diff --git a/gdb/language.h b/gdb/language.h
index ba28540..cc10ff2 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -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 */
diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
index 2b3ca6a..ea59403 100644
--- a/gdb/m2-lang.c
+++ b/gdb/m2-lang.c
@@ -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 */
diff --git a/gdb/macrocmd.c b/gdb/macrocmd.c
index c9ab440..56e9a48 100644
--- a/gdb/macrocmd.c
+++ b/gdb/macrocmd.c
@@ -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);
}
diff --git a/gdb/macrotab.c b/gdb/macrotab.c
index 7633c98..c33c028 100644
--- a/gdb/macrotab.c
+++ b/gdb/macrotab.c
@@ -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)
+{
+ 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)
{
- /* 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 = (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);
}
diff --git a/gdb/macrotab.h b/gdb/macrotab.h
index 71f1d3e..25b4c5f 100644
--- a/gdb/macrotab.h
+++ b/gdb/macrotab.h
@@ -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);
-
-/* Call the function FN for each macro in the macro table TABLE. */
-void macro_for_each (struct macro_table *table, macro_callback_fn fn);
+ const struct macro_definition *definition,
+ void *user_data);
+
+/* 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 */
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index 4608168..553080a 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -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,
diff --git a/gdb/p-lang.c b/gdb/p-lang.c
index b829f8d..7ecdd8d 100644
--- a/gdb/p-lang.c
+++ b/gdb/p-lang.c
@@ -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,
diff --git a/gdb/scm-lang.c b/gdb/scm-lang.c
index 607efb6..42d2502 100644
--- a/gdb/scm-lang.c
+++ b/gdb/scm-lang.c
@@ -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,
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 10987e2..437d414 100644
--- a/gdb/symtab.c
+++ b/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);
}
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 60adacf..d4d0811 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,12 @@
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"
everywhere.
* gdb.base/macscp1.c (MACRO_TO_EXPAND): Rename from "M".
diff --git a/gdb/testsuite/gdb.base/macscp.exp b/gdb/testsuite/gdb.base/macscp.exp
index 152e006..2a43a28 100644
--- a/gdb/testsuite/gdb.base/macscp.exp
+++ b/gdb/testsuite/gdb.base/macscp.exp
@@ -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)" \
diff --git a/gdb/testsuite/gdb.base/macscp1.c b/gdb/testsuite/gdb.base/macscp1.c
index 0be78c6..40f1217 100644
--- a/gdb/testsuite/gdb.base/macscp1.c
+++ b/gdb/testsuite/gdb.base/macscp1.c
@@ -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)
{