* RFA: PR 2484: completion of macro names
@ 2008-07-29 20:39 Tom Tromey
2008-07-29 20:49 ` regression test on the compile farm Thiago Jung Bauermann
2008-09-28 22:01 ` RFA: PR 2484: completion of macro names Pedro Alves
0 siblings, 2 replies; 8+ messages in thread
From: Tom Tromey @ 2008-07-29 20:39 UTC (permalink / raw)
To: gdb-patches
This patch fixes PR gdb/2484. The bug here is that TAB completion
does not complete macro names.
This patch adds a new la_macro_expansion field to struct
language_defn, and updates all the languages. (It also fixes a bug in
field ordering in a couple language initializers.)
It also adds a callback argument to macro_for_each.
In keeping with my understanding of Jim's wishes for the macro code, I
made the new macro_for_each_in_scope take an explicit pair of
file/line arguments, rather than a macro_scope. This means that
macrotab.c still can remain blissfully ignorant of struct macro_scope.
The guts of the change are in symtab.c. The patch changes
default_make_symbol_completion_list to look at all the macros in scope,
plus all the user-defined macros.
Built and regression tested on the compile farm (x86-64).
A couple new test cases included.
Ok?
Tom
2008-07-28 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 (struct macro_scope): Declare.
(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.
* 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.
* Makefile.in (symtab.o): Add macroscope_h, macrotab_h.
b/gdb/testsuite/ChangeLog:
2008-07-28 Tom Tromey <tromey@redhat.com>
* gdb.base/macscp1.c (FIFTY_SEVEN): New macro.
(TWENTY_THREE): Likewise.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index a24e29b..295455f 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2904,7 +2904,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
$(filenames_h) $(objc_lang_h) $(ada_lang_h) $(hashtab_h) \
$(gdb_obstack_h) $(block_h) $(dictionary_h) $(gdb_string_h) \
$(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h) \
- $(solist_h) $(p_lang_h) $(addrmap_h)
+ $(solist_h) $(p_lang_h) $(addrmap_h) $(macrotab_h) $(macroscope_h)
target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
$(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index f3f1f34..5aabcdd 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10934,6 +10934,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,
+ 0,
&ada_exp_descriptor,
parse,
ada_error,
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index 9ce4bb9..d467587 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -390,6 +390,7 @@ const struct language_defn c_language_defn =
type_check_off,
case_sensitive_on,
array_row_major,
+ 1,
&exp_descriptor_standard,
c_preprocess_and_parse,
c_error,
@@ -503,6 +504,7 @@ const struct language_defn cplus_language_defn =
type_check_off,
case_sensitive_on,
array_row_major,
+ 1,
&exp_descriptor_standard,
c_preprocess_and_parse,
c_error,
@@ -538,6 +540,7 @@ const struct language_defn asm_language_defn =
type_check_off,
case_sensitive_on,
array_row_major,
+ 1,
&exp_descriptor_standard,
c_preprocess_and_parse,
c_error,
@@ -578,6 +581,7 @@ const struct language_defn minimal_language_defn =
type_check_off,
case_sensitive_on,
array_row_major,
+ 1,
&exp_descriptor_standard,
c_preprocess_and_parse,
c_error,
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 5dcbd33..813cef7 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -313,6 +313,7 @@ const struct language_defn f_language_defn =
type_check_on,
case_sensitive_off,
array_column_major,
+ 0,
&exp_descriptor_standard,
f_parse, /* parser */
f_error, /* parser error function */
diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c
index 6080839..4686c7b 100644
--- a/gdb/jv-lang.c
+++ b/gdb/jv-lang.c
@@ -1057,6 +1057,7 @@ const struct language_defn java_language_defn =
type_check_off,
case_sensitive_on,
array_row_major,
+ 0,
&exp_descriptor_java,
java_parse,
java_error,
diff --git a/gdb/language.c b/gdb/language.c
index 66e5542..b5c8173 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -1179,8 +1179,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,
+ 0,
&exp_descriptor_standard,
unk_lang_parser,
unk_lang_error,
@@ -1215,8 +1216,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,
+ 0,
&exp_descriptor_standard,
unk_lang_parser,
unk_lang_error,
@@ -1252,6 +1254,7 @@ const struct language_defn local_language_defn =
type_check_off,
case_sensitive_on,
array_row_major,
+ 0,
&exp_descriptor_standard,
unk_lang_parser,
unk_lang_error,
diff --git a/gdb/language.h b/gdb/language.h
index 8bdc212..efea145 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -153,6 +153,9 @@ struct language_defn
/* Multi-dimensional array ordering */
enum array_ordering la_array_ordering;
+ /* True if this language supports C-like macro expansion. */
+ unsigned int la_macro_expansion : 1;
+
/* Definitions related to expression printing, prefixifying, and
dumping */
diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
index bb205ad..5e7c111 100644
--- a/gdb/m2-lang.c
+++ b/gdb/m2-lang.c
@@ -364,6 +364,7 @@ const struct language_defn m2_language_defn =
type_check_on,
case_sensitive_on,
array_row_major,
+ 0,
&exp_descriptor_modula2,
m2_parse, /* parser */
m2_error, /* parser error function */
diff --git a/gdb/macrocmd.c b/gdb/macrocmd.c
index 4a70d4f..030251a 100644
--- a/gdb/macrocmd.c
+++ b/gdb/macrocmd.c
@@ -318,7 +318,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)
@@ -339,7 +340,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..a96d4af 100644
--- a/gdb/macrotab.c
+++ b/gdb/macrotab.c
@@ -887,25 +887,66 @@ 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;
+
+ if (compare_locations (key->start_file, key->start_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 5ff36ea..25a6b88 100644
--- a/gdb/macrotab.h
+++ b/gdb/macrotab.h
@@ -75,6 +75,9 @@ struct macro_table;
/* The definition of a single macro. */
struct macro_definition;
+/* A macro scope. */
+struct macro_scope;
+
/* A source file that participated in a compilation unit --- either a
main file, or an #included file. If a file is #included more than
once, the presence of the `included_from' and `included_at_line'
@@ -305,12 +308,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 56871e3..4ac1d33 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -497,6 +497,7 @@ const struct language_defn objc_language_defn = {
type_check_off,
case_sensitive_on,
array_row_major,
+ 1,
&exp_descriptor_standard,
objc_parse,
objc_error,
diff --git a/gdb/p-lang.c b/gdb/p-lang.c
index 2accf35..e9329f1 100644
--- a/gdb/p-lang.c
+++ b/gdb/p-lang.c
@@ -403,6 +403,7 @@ const struct language_defn pascal_language_defn =
type_check_on,
case_sensitive_on,
array_row_major,
+ 0,
&exp_descriptor_standard,
pascal_parse,
pascal_error,
diff --git a/gdb/scm-lang.c b/gdb/scm-lang.c
index 991e4b4..0020a57 100644
--- a/gdb/scm-lang.c
+++ b/gdb/scm-lang.c
@@ -240,6 +240,7 @@ const struct language_defn scm_language_defn =
type_check_off,
case_sensitive_off,
array_row_major,
+ 0,
&exp_descriptor_scm,
scm_parse,
c_error,
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 2ab520d..2ea1a96 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 */
@@ -3636,6 +3638,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)
{
@@ -3822,6 +3847,32 @@ default_make_symbol_completion_list (char *text, char *word)
}
}
+ if (current_language->la_macro_expansion)
+ {
+ 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. 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/gdb.base/macscp.exp b/gdb/testsuite/gdb.base/macscp.exp
index 15d3f2f..290f040 100644
--- a/gdb/testsuite/gdb.base/macscp.exp
+++ b/gdb/testsuite/gdb.base/macscp.exp
@@ -477,3 +477,58 @@ gdb_test "print M" \
gdb_test "macro expand SPLICE(x, y)" \
"Token splicing is not implemented yet." \
"macro splicing lexes correctly"
+
+
+# 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" }
+ }
+
+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" }
+ }
diff --git a/gdb/testsuite/gdb.base/macscp1.c b/gdb/testsuite/gdb.base/macscp1.c
index 200ac26..3ac41c6 100644
--- a/gdb/testsuite/gdb.base/macscp1.c
+++ b/gdb/testsuite/gdb.base/macscp1.c
@@ -5,6 +5,8 @@
#define STRINGIFY(a) INNER_STRINGIFY(a)
#define INNER_STRINGIFY(a) #a
+#define FIFTY_SEVEN 57
+
/* A macro named UNTIL_<func> is #defined until just before the
definition of the function <func>.
@@ -75,6 +77,8 @@ macscp_expr (void)
foo = 2;
}
+#define TWENTY_THREE 23
+
int
main (int argc, char **argv)
{
^ permalink raw reply [flat|nested] 8+ messages in thread
* regression test on the compile farm
2008-07-29 20:39 RFA: PR 2484: completion of macro names Tom Tromey
@ 2008-07-29 20:49 ` Thiago Jung Bauermann
2008-07-29 21:39 ` Tom Tromey
2008-09-28 22:01 ` RFA: PR 2484: completion of macro names Pedro Alves
1 sibling, 1 reply; 8+ messages in thread
From: Thiago Jung Bauermann @ 2008-07-29 20:49 UTC (permalink / raw)
To: tromey; +Cc: gdb-patches
On Tue, 2008-07-29 at 14:38 -0600, Tom Tromey wrote:
> Built and regression tested on the compile farm (x86-64).
Pray tell, is that wondrous compile farm available to other gdb
developers as well? :-)
--
[]'s
Thiago Jung Bauermann
Software Engineer
IBM Linux Technology Center
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: regression test on the compile farm
2008-07-29 20:49 ` regression test on the compile farm Thiago Jung Bauermann
@ 2008-07-29 21:39 ` Tom Tromey
0 siblings, 0 replies; 8+ messages in thread
From: Tom Tromey @ 2008-07-29 21:39 UTC (permalink / raw)
To: Thiago Jung Bauermann; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1850 bytes --]
>>>>> "Thiago" == Thiago Jung Bauermann <bauerman@br.ibm.com> writes:
Tom> Built and regression tested on the compile farm (x86-64).
Thiago> Pray tell, is that wondrous compile farm available to other gdb
Thiago> developers as well? :-)
Sure. It is the GCC Compile Farm. You can get an account, see:
http://gcc.gnu.org/wiki/CompileFarm
I am running a modified copy of Sebastian Pop's GCC patch-testing
script. This variant is specific to gdb, and in particular uses Jim
Meyering's git clone of gdb CVS -- this is necessary to set a known
baseline for a patch. Note that this means you have to make your
patch against the git repository.
I can send out my scripts and whatnot... I have gdb_tester.sh (run on
the server), plus a "mkdiff" (a wrapper for git diff that stuffs in
some metadata that the tester uses -- and lets you tweak the
configure/make/etc options) and "submit-patch" (send mkdiff output to
the tester).
So, a typical scenario is: hack hack hack; "mkdiff > Patches/whatever.diff";
"submit-patch Patches/whatever.diff". Then after a short time I get
email saying how it went :)
Instead of having everybody set up a separate tester, though, I am
thinking I will just make my 'patches' directory writable. Then we
can all share an instance... this should be ok since I am not using it
all that heavily. (If enough of us share it we could look into more
infrastructure, say a status-reporting irc bot or buildbot setup or
something.)
If someone wants to volunteer to be the first to try it out, let me
know offline and I will set up permissions.
I've attached the scripts; please report problems, send patches to
them, etc, to me. Thanks.
I've also been thinking about setting up a compile farm job to run the
gdb test suite against gcc svn trunk. But, maybe somebody else would
like to volunteer for that ;)
Tom
[-- Attachment #2: mkdiff --]
[-- Type: application/octet-stream, Size: 4326 bytes --]
#!/bin/sh
# Copyright (C) 2003, 2008 Free Software Foundation
# This script is Free Software, and it can be copied, distributed and
# modified as defined in the GNU General Public License. A copy of
# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html
# Written by Tom Tromey <tromey@redhat.com>
# mkdiff version 2.0
# Usage: mkdiff [OPTION]... [FILE]...
# Make a patch suitable for submission to the GCC patch tester.
# The diff is made relative to the top of the tree, but the FILE
# options are relative the working directory, so this can be invoked
# exactly as one would invoke "svn diff" or "git diff", depending on
# the working tree.
# --email=ADDR email address to use (default currentuser@gcc.gnu.org)
# --branch=BRANCH branch to use (default from working directory)
# --revision=REV revision to use (default from working directory)
# --config=OPTSTR set configure options (default none)
# --make=OPTSTR set make options (default none)
# --check=OPTSTR set check options (default none)
# --help print this help, then exit
# --version print version number, then exit
# Unrecognized options are assumed to be options to "svn diff"
# or "git diff".
if test -d .svn; then
vc=svn
elif git status -a > /dev/null 2>&1; then
vc=git
else
echo "$name: not in SVN or git-controlled directory" 1>&2
exit 1
fi
name=mkdiff
diffopts=
email=`id -un`@gcc.gnu.org
branch=
revision=
files=
configopts=
makeopts=
checkopts=
# Parsing loop taken from Alexandre Oliva's cvs scripts.
while test $# -gt 0; do
case "$1" in
-v|--version)
sed '/^# '$name' version / { s/^# //; p; }; d' < $0
exit 0
;;
-\?|-h)
sed '/^# usage:/ { s/^# //; p; }; d' < $0 &&
echo
echo "run \`$name --help | more' for full usage"
exit 0
;;
--help)
sed '/^# '$name' version /,/^[^#]/ { /^[^#]/ d; s/^# //; p; }; d' < $0
exit 0
;;
--email=*)
email=`echo "$1" | sed -e 's,--email=,,'`
;;
--branch=*)
branch=`echo "$1" | sed -e 's,--branch=,,'`
;;
--revision=*)
revision=`echo "$1" | sed -e 's,--revision=,,'`
;;
--check=*)
checkopts=`echo "$1" | sed -e 's,--check=,,'`
;;
--make=*)
makeopts=`echo "$1" | sed -e 's,--make=,,'`
;;
--config=*)
configopts=`echo "$1" | sed -e 's,--config=,,'`
;;
-*)
diffopts="$diffopts $1"
;;
*)
files="$files $1"
;;
esac
shift
done
if test $vc = svn; then
if test -z "$branch"; then
repo=`svn info | grep '^URL:' | sed -e 's,^URL: ,,'`
case $repo in
*/gcc.gnu.org/svn/gcc/trunk*)
branch=trunk
;;
*/gcc.gnu.org/svn/gcc/branches/*)
branch=`echo $repo | sed 's,.*/branches/\([^/]*\).*$,\1,'`
;;
*)
echo "$name: unrecognized repository, use --branch: $repo" 1>&2
exit 1
;;
esac
fi
if test -z "$revision"; then
revision=`svn info | grep '^Revision:' | sed -e 's,^Revision: ,,'`
fi
else
if test -z "$revision"; then
revision=`git log | sed -e 's,^commit *,,' -e 1q`
fi
fi
here=`pwd`
orig=$here
dirname=
cdie() {
cd $1 || {
echo "$name: couldn't cd to $1 from `pwd`" 1>&2
exit 1
}
}
if test $vc = svn; then
while test -e ../.svn; do
cdie ..
next=`basename "$here"`
here=`dirname "$here"`
if test -z "$dirname"; then
dirname="$next/"
else
dirname="$next/$dirname"
fi
done
projecttestdir=.
else
# We want to find the project type, but we don't have to bother
# with computing the directory properly -- git diff handles this
# itself.
save=`pwd`
while ! test -e .git; do
cdie ..
done
projecttestdir=`pwd`
cd $save
fi
if test -d $projecttestdir/gcc; then
projecttype=gcc
elif test -d $projecttestdir/gdb; then
projecttype=gdb
else
echo "$name: couldn't determine project type in $projecttestdir" 1>&2
exit 1
fi
if test -z "$files"; then
files=.
fi
# We don't use filterdiff -addprefix since that does not seem to
# handle Index: lines.
newfiles=
for file in $files; do
newfiles="$newfiles $dirname$file"
done
echo "projecttype:$projecttype"
echo "email:$email"
if test $vc = svn; then
echo "branch:$branch"
fi
echo "revision:$revision"
echo "configure:$configopts"
echo "make:$makeopts"
echo "check:$checkopts"
echo
$vc diff $diffopts $newfiles
[-- Attachment #3: submit-patch --]
[-- Type: application/octet-stream, Size: 2754 bytes --]
#! /bin/sh
# Copyright (C) 2003, 2008 Free Software Foundation
# This script is Free Software, and it can be copied, distributed and
# modified as defined in the GNU General Public License. A copy of
# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html
# Written by Tom Tromey <tromey@redhat.com>
# submit-patch version 2.0
# Usage: submit-patch [OPTION]... PATCH-FILE [NAME]
# Regression test a GCC patch.
# --host=HOST host to use
# --dir=DIR directory to use on host
# --help print this help, then exit
# --version print version number, then exit
# If NAME is not given, the basename of the patch file is used as
# the patch name.
name=submit-patch
repeat="test $# -gt 0"
host=gcc13.fsffrance.org
# This is used to construct the patch dir if --dir is not given.
patchbase=/home/tromey/auto-test-
# Parsing loop taken from Alexandre Oliva's cvs scripts.
while $repeat; do
case "$1" in
-v|--version)
sed '/^# '$name' version / { s/^# //; p; }; d' < $0
exit 0
;;
-\?|-h)
sed '/^# usage:/ { s/^# //; p; }; d' < $0 &&
echo
echo "run \`$name --help | more' for full usage"
exit 0
;;
--help)
sed '/^# '$name' version /,/^[^#]/ { /^[^#]/ d; s/^# //; p; }; d' < $0
exit 0
;;
--host=*)
host=`echo "$1" | sed -e 's,--host=,,'`
shift
;;
--dir=*)
patchdir=`echo "$1" | sed -e 's,--dir=,,'`
shift
;;
--)
shift
repeat=false
;;
-*)
echo "$name: unrecognized option '$1'" 1>&2
echo "$name: Try '$name --help' for more information" 1>&2
exit 1
;;
*)
repeat=false
;;
esac
done
file=$1
shift
if test -z "$file"; then
(sed '/^# usage:/ { s/^# //; p; }; d' < $0 &&
echo
echo "run \`$name --help | more' for full usage") 1>&2
exit 1
fi
patch=$1
shift
if test -z "$patch"; then
if test "x$file" = "x-"; then
echo "$name: NAME argument required if patch is from stdin" 1>&2
exit 1
else
patch=`basename $file`
fi
fi
if test "x$file" != "x-"; then
if ! grep -s "^email:" $file > /dev/null; then
echo "$name: no email: line in $file; did you use mkdiff?" 1>&2
exit 1
fi
fi
if test -z "$patchdir"; then
if test "x$file" = "x-"; then
echo "$name: --dir required if patch is from stdin" 1>&2
exit 1
fi
project=`sed -n -e 's/^projecttype://p' -e '/^$/q' $file`
patchdir=$patchbase$project/patches
fi
# Only run filterdiff on a known non-git patch.
filter=cat
if test "x$file" != "x-"; then
if ! grep -s "diff --git" $file > /dev/null; then
filter="filterdiff -x '*ChangeLog*'"
fi
fi
# FIXME: may be nice to auto-start the patch tester.
# Use 'cat' here so we can accept "-".
cat $file | $filter | ssh $host cat '>' $patchdir/`id -un`-$patch
[-- Attachment #4: gdb_tester.sh --]
[-- Type: application/x-sh, Size: 11130 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFA: PR 2484: completion of macro names
2008-07-29 20:39 RFA: PR 2484: completion of macro names Tom Tromey
2008-07-29 20:49 ` regression test on the compile farm Thiago Jung Bauermann
@ 2008-09-28 22:01 ` Pedro Alves
2008-09-30 16:13 ` Tom Tromey
1 sibling, 1 reply; 8+ messages in thread
From: Pedro Alves @ 2008-09-28 22:01 UTC (permalink / raw)
To: gdb-patches, tromey
Hi Tom,
Thanks a lot for doing this. I'd love to get this feature in, and
it seems no one has reviewed it yet, so here's my try at grasping
it. Please see comments below.
On Tuesday 29 July 2008 21:38:48, Tom Tromey wrote:
> +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;
> +
> + if (compare_locations (key->start_file, key->start_line,
> + datum->file, datum->line) < 0)
> + (*datum->fn) (key->name, def, datum->user_data);
> + return 0;
> +}
This matches macros that have been undefined before the
current line, was that intended? E.g.,
define FOO 1
#define BAR 2
#undef FOO
int main ()
{
return 0; <<< stop here
}
This will still complete p F<tab>OO, but then
if the user tries to evaluate it the user will
get, correcty:
(gdb) p FOO
No symbol "FOO" in current context.
(gdb)
I think you want something along the lines of:
if (compare_locations (key->start_file, key->start_line,
datum->file, datum->line) < 0
&& (key->end_file == 0
|| compare_locations (key->end_file, key->end_line,
datum->file, datum->line) >= 0))
(*datum->fn) (key->name, def, datum->user_data);
?
> + /* 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. 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);
> + }
I'm a bonehead, and don't follow this :-). Could you show/add here
an example of one such case, that would matter for completion?
> --- a/gdb/language.h
> +++ b/gdb/language.h
> @@ -153,6 +153,9 @@ struct language_defn
> /* Multi-dimensional array ordering */
> enum array_ordering la_array_ordering;
>
> + /* True if this language supports C-like macro expansion. */
> + unsigned int la_macro_expansion : 1;
> +
We're already being inconsistent by using enum as flags in this
structure (e.g., case_sensitivity), or char's as flags (c_style_arrays).
This adds yet a third way to do things. IMVHO, we should strive for
consistency. Since several other language flags are enums, and
since there aren't that many languages that we have to consider
space savings here, making this an enum as well would make these,
> case_sensitive_on,
> array_row_major,
> + 0,
> &exp_descriptor_modula2,
... easier to read. Again, this is a IMVHO.
> --- a/gdb/jv-lang.c
> +++ b/gdb/jv-lang.c
> @@ -1057,6 +1057,7 @@ const struct language_defn java_language_defn =
> type_check_off,
> case_sensitive_on,
> array_row_major,
> + 0,
> &exp_descriptor_java,
> java_parse,
> java_error,
Out of curiosity --- can one use the C preprocessor with gcj? Will
gcj output macro debug info with -g3 in that case? (Or any
other non-C frontend for the matter)
--
Pedro Alves
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFA: PR 2484: completion of macro names
2008-09-28 22:01 ` RFA: PR 2484: completion of macro names Pedro Alves
@ 2008-09-30 16:13 ` Tom Tromey
2008-09-30 16:54 ` Pedro Alves
0 siblings, 1 reply; 8+ messages in thread
From: Tom Tromey @ 2008-09-30 16:13 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
Pedro> This matches macros that have been undefined before the
Pedro> current line, was that intended? E.g.,
[...]
Thanks. I fixed this and added a new test.
Pedro> I'm a bonehead, and don't follow this :-). Could you show/add here
Pedro> an example of one such case, that would matter for completion?
I added an example.
Pedro> Since several other language flags are enums, and since there
Pedro> aren't that many languages that we have to consider space
Pedro> savings here, making this an enum as well would make these,
Done.
Pedro> Out of curiosity --- can one use the C preprocessor with gcj?
No.
Pedro> (Or any other non-C frontend for the matter)
Fortran allows macro expansion now. I did not change this, because it
also requires changes to the Fortran lexer in gdb. I think that is
outside the scope of this patch. Perhaps a Fortran maintainer could
implement it.
Here's the updated patch. Built and regtested on x86-64.
Tom
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 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.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 7176561..132e89e 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 ebe781b..ce75345 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,
@@ -508,6 +509,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,
@@ -543,6 +545,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,
@@ -583,6 +586,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 8ae7775..7339aa4 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 39d8f48..260d1cf 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 7b0b44a..84a1f6c 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,
@@ -1171,8 +1172,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,
@@ -1208,6 +1210,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 04d4da2..ee84eab 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -113,6 +113,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
+ };
+
\f
/* Per architecture (OS/ABI) language information. */
@@ -158,6 +169,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 : 1;
+
/* Definitions related to expression printing, prefixifying, and
dumping */
diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
index 8bc0ce7..c3226fc 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 8213c0d..bea5c08 100644
--- a/gdb/macrocmd.c
+++ b/gdb/macrocmd.c
@@ -326,7 +326,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)
@@ -347,7 +348,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 1692c3d..8d88758 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 b763e04..45755ce 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 003e27a..5dea59a 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/gdb.base/macscp.exp b/gdb/testsuite/gdb.base/macscp.exp
index 3424714..426c98d 100644
--- a/gdb/testsuite/gdb.base/macscp.exp
+++ b/gdb/testsuite/gdb.base/macscp.exp
@@ -484,3 +484,74 @@ gdb_test "macro undef" \
gdb_test "macro expand SPLICE(x, y)" \
"Token splicing is not implemented yet." \
"macro splicing lexes correctly"
+
+
+# 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" }
+ }
diff --git a/gdb/testsuite/gdb.base/macscp1.c b/gdb/testsuite/gdb.base/macscp1.c
index 200ac26..97d6b49 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)
{
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFA: PR 2484: completion of macro names
2008-09-30 16:13 ` Tom Tromey
@ 2008-09-30 16:54 ` Pedro Alves
2008-09-30 17:25 ` Tom Tromey
2008-10-01 17:46 ` Tom Tromey
0 siblings, 2 replies; 8+ messages in thread
From: Pedro Alves @ 2008-09-30 16:54 UTC (permalink / raw)
To: gdb-patches, Tom Tromey
On Tuesday 30 September 2008 17:07:49, Tom Tromey wrote:
> Fortran allows macro expansion now. I did not change this, because it
> also requires changes to the Fortran lexer in gdb. I think that is
> outside the scope of this patch. Perhaps a Fortran maintainer could
> implement it.
Certainly. Thanks for the clarifications.
> + /* Style of macro expansion, if any, supported by this language. */
> + enum macro_expansion la_macro_expansion : 1;
Left over ` : 1'.
> + /* 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 ();
Ah, thanks. This isn't much different from local symbols,
which we use the selected frame/block.
:REVIEWMAIL:
Looks OK to me. Thanks again for doing this.
> 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 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.
>
--
Pedro Alves
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFA: PR 2484: completion of macro names
2008-09-30 16:54 ` Pedro Alves
@ 2008-09-30 17:25 ` Tom Tromey
2008-10-01 17:46 ` Tom Tromey
1 sibling, 0 replies; 8+ messages in thread
From: Tom Tromey @ 2008-09-30 17:25 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
>>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
>> + /* Style of macro expansion, if any, supported by this language. */
>> + enum macro_expansion la_macro_expansion : 1;
Pedro> Left over ` : 1'.
Thanks, I fixed this.
Pedro> Looks OK to me. Thanks again for doing this.
I checked it in.
Tom
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFA: PR 2484: completion of macro names
2008-09-30 16:54 ` Pedro Alves
2008-09-30 17:25 ` Tom Tromey
@ 2008-10-01 17:46 ` Tom Tromey
1 sibling, 0 replies; 8+ messages in thread
From: Tom Tromey @ 2008-10-01 17:46 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
Pedro> Fortran allows macro expansion now. I did not change this, because it
Pedro> also requires changes to the Fortran lexer in gdb. I think that is
Pedro> outside the scope of this patch. Perhaps a Fortran maintainer could
Pedro> implement it.
Pedro> Certainly. Thanks for the clarifications.
Oh, btw -- I filed a PR about preprocessing and fortran a while ago, I
think when I wrote the patch. It is PR 2504.
Tom
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-10-01 17:46 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-07-29 20:39 RFA: PR 2484: completion of macro names Tom Tromey
2008-07-29 20:49 ` regression test on the compile farm Thiago Jung Bauermann
2008-07-29 21:39 ` Tom Tromey
2008-09-28 22:01 ` RFA: PR 2484: completion of macro names Pedro Alves
2008-09-30 16:13 ` Tom Tromey
2008-09-30 16:54 ` Pedro Alves
2008-09-30 17:25 ` Tom Tromey
2008-10-01 17:46 ` Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox