This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[commit] Improve FILE:FUNCTION support in decode_line_1
- From: Daniel Jacobowitz <dan at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 16 Feb 2010 16:06:56 -0500
- Subject: [commit] Improve FILE:FUNCTION support in decode_line_1
Due to a local patch (specifically, my earlier version of Keith's
DW_AT_MIPS_linkage_name physname patch, which is pending for GDB 7.1),
the gdb.cp/extern-c.exp testcase tries to set breakpoints which look
like /path/to/extern-c.cc:'c_funcs_1()'. Currently, this fails.
This patch improves the situation a bit. This already worked:
+gdb_test "list ${srcfile}:intToChar" "int intToChar.*"
These three cases, previously unsupported, now work also:
+gdb_test "list ${srcfile}:intToChar(char)" "int intToChar.*"
+gdb_test "list ${srcfile}:'intToChar(char)'" "int intToChar.*"
+gdb_test "list '${srcfile}:intToChar(char)'" "int intToChar.*"
I believe these are all intended to work, judging by the code in
linespec.c. They fail in a variety of ways, for instance the last one
tries to look up a function named "intToChar(char)'" (including the
trailing single quote).
I found a related bug in locate_first_half that prevents this from
working in a class or namespace; that one wasn't immediately causing
me trouble, so I filed PR c++/11289 to record it for later and added
some tests.
The patch itself follows closely from the description above.
* Do not restrict file symtab lookups to strings containing no
parentheses. foo.cc:intToChar and foo.cc:intToChar(char) took
completely different code paths. The check was supposed to
distinguish foo::intToChar from foo::intToChar().
* Check again for a single quote after finding a filename. This was
already happening - but only if there were no parentheses.
* Save the location of the final quote so that we know what character
to remove.
Tested on arm-none-eabi and x86_64-linux; committed to trunk.
--
Daniel Jacobowitz
CodeSourcery
2010-02-16 Daniel Jacobowitz <dan@codesourcery.com>
gdb/
* linespec.c (decode_line_1): Handle FILE:FUNCTION even if
FUNCTION contains parentheses. Improve removal of a trailing
single quote.
gdb/testsuite/
* gdb.base/list.exp (test_list_filename_and_function): Add test
with single quotes.
* gdb.cp/overload.cc (intToChar): Rewrite onto one line for easy
matching.
* gdb.cp/overload.exp: Add tests with filename, function, and quotes.
Add KFAIL'd tests for PR gdb/11289.
---
gdb/linespec.c | 44 ++++++++++++++++++++++++++++----------
gdb/testsuite/gdb.base/list.exp | 3 ++
gdb/testsuite/gdb.cp/overload.cc | 5 ----
gdb/testsuite/gdb.cp/overload.exp | 15 ++++++++++++
4 files changed, 52 insertions(+), 15 deletions(-)
Index: src/gdb/linespec.c
===================================================================
--- src.orig/gdb/linespec.c 2010-01-13 13:31:26.000000000 -0500
+++ src/gdb/linespec.c 2010-02-16 14:36:47.000000000 -0500
@@ -698,6 +698,8 @@ decode_line_1 (char **argptr, int funfir
int is_quote_enclosed;
int is_objc_method = 0;
char *saved_arg = *argptr;
+ /* If IS_QUOTED, the end of the quoted bit. */
+ char *end_quote = NULL;
if (not_found_ptr)
*not_found_ptr = 0;
@@ -717,6 +719,8 @@ decode_line_1 (char **argptr, int funfir
*/
set_flags (*argptr, &is_quoted, &paren_pointer);
+ if (is_quoted)
+ end_quote = skip_quoted (*argptr);
/* Check to see if it's a multipart linespec (with colons or
periods). */
@@ -747,13 +751,13 @@ decode_line_1 (char **argptr, int funfir
return values;
}
+ if (is_quoted)
+ *argptr = *argptr + 1;
+
/* Does it look like there actually were two parts? */
- if ((p[0] == ':' || p[0] == '.') && paren_pointer == NULL)
+ if (p[0] == ':' || p[0] == '.')
{
- if (is_quoted)
- *argptr = *argptr + 1;
-
/* Is it a C++ or Java compound data structure?
The check on p[1] == ':' is capturing the case of "::",
since p[0]==':' was checked above.
@@ -762,14 +766,30 @@ decode_line_1 (char **argptr, int funfir
can return now. */
if (p[0] == '.' || p[1] == ':')
- return decode_compound (argptr, funfirstline, canonical,
- saved_arg, p, not_found_ptr);
+ {
+ if (paren_pointer == NULL)
+ return decode_compound (argptr, funfirstline, canonical,
+ saved_arg, p, not_found_ptr);
+ /* Otherwise, fall through to decode_variable below. */
+ }
+ else
+ {
+ /* No, the first part is a filename; set file_symtab to be that file's
+ symtab. Also, move argptr past the filename. */
- /* No, the first part is a filename; set file_symtab to be that file's
- symtab. Also, move argptr past the filename. */
+ file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed,
+ not_found_ptr);
- file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed,
- not_found_ptr);
+ /* Check for single quotes on the non-filename part. */
+ if (!is_quoted)
+ {
+ is_quoted = (**argptr
+ && strchr (get_gdb_completer_quote_characters (),
+ **argptr) != NULL);
+ if (is_quoted)
+ end_quote = skip_quoted (*argptr);
+ }
+ }
}
#if 0
/* No one really seems to know why this was added. It certainly
@@ -829,7 +849,7 @@ decode_line_1 (char **argptr, int funfir
p = skip_quoted (*argptr + (((*argptr)[1] == '$') ? 2 : 1));
else if (is_quoted)
{
- p = skip_quoted (*argptr);
+ p = end_quote;
if (p[-1] != '\'')
error (_("Unmatched single quote."));
}
@@ -862,6 +882,8 @@ decode_line_1 (char **argptr, int funfir
copy[p - *argptr - 1] = '\0';
copy++;
}
+ else if (is_quoted)
+ copy[p - *argptr - 1] = '\0';
while (*p == ' ' || *p == '\t')
p++;
*argptr = p;
Index: src/gdb/testsuite/gdb.base/list.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.base/list.exp 2010-02-16 14:24:22.000000000 -0500
+++ src/gdb/testsuite/gdb.base/list.exp 2010-02-16 14:28:20.000000000 -0500
@@ -473,6 +473,9 @@ proc test_list_filename_and_function {}
pass "list filename:function ($testcnt tests)"
+ # Test with quoting.
+ gdb_test "list 'list0.c:main'" "int main.*"
+
# Test some invalid specs
# The following test takes the FIXME result on most systems using
# DWARF. It fails to notice that main() is not in the file requested.
Index: src/gdb/testsuite/gdb.cp/overload.cc
===================================================================
--- src.orig/gdb/testsuite/gdb.cp/overload.cc 2010-02-16 14:35:21.000000000 -0500
+++ src/gdb/testsuite/gdb.cp/overload.cc 2010-02-16 14:35:29.000000000 -0500
@@ -56,10 +56,7 @@ namespace N {
int nsoverload (int x, int y) { return x + y; }
};
-int intToChar (char c)
-{
- return 297;
-}
+int intToChar (char c) { return 297; }
void marker1()
{}
Index: src/gdb/testsuite/gdb.cp/overload.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.cp/overload.exp 2010-02-16 14:22:27.000000000 -0500
+++ src/gdb/testsuite/gdb.cp/overload.exp 2010-02-16 14:35:42.000000000 -0500
@@ -293,6 +293,21 @@ gdb_test "list \"foo::overloadfnarg(int,
"int foo::overloadfnarg.*\\(int arg, int \\(\\*foo\\) \\(int\\)\\).*" \
"list overloaded function with function ptr args - quotes around argument"
+# Test list with filename.
+
+gdb_test "list ${srcfile}:intToChar" "int intToChar.*"
+gdb_test "list ${srcfile}:intToChar(char)" "int intToChar.*"
+gdb_test "list ${srcfile}:'intToChar(char)'" "int intToChar.*"
+gdb_test "list '${srcfile}:intToChar(char)'" "int intToChar.*"
+
+# And with filename and namespace... which does not work.
+
+setup_kfail *-*-* gdb/11289
+gdb_test "list ${srcfile}:foo::overloadfnarg(int)" "int foo::overloadfnarg"
+
+setup_kfail *-*-* gdb/11289
+gdb_test "list ${srcfile}:'foo::overloadfnarg(int)'" "int foo::overloadfnarg"
+
# Now some tests to see how overloading and namespaces interact.
gdb_test "print overloadNamespace(1)" ".\[0-9\]* = 1"