aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorKeith Seitz <keiths@redhat.com>2011-03-16 21:12:12 +0000
committerKeith Seitz <keiths@redhat.com>2011-03-16 21:12:12 +0000
commitc00f848495bbc6e6b24d4ec81d64a09f5759bf3d (patch)
treed95cbfa0489f1fff9ebe2d1d1d9fc6a6069ff4de /gdb
parent598997c828bff87692dc5addca8b7961f227918b (diff)
downloadgdb-c00f848495bbc6e6b24d4ec81d64a09f5759bf3d.zip
gdb-c00f848495bbc6e6b24d4ec81d64a09f5759bf3d.tar.gz
gdb-c00f848495bbc6e6b24d4ec81d64a09f5759bf3d.tar.bz2
* linespec.c (find_methods): Canonicalize NAME before looking
up the symbol. (name_end): New function. (keep_name_info): New function. (decode_line_1): Use keep_name_info. (decode_compound): Likewise. * cli/cli-utils.h (remove_trailing_whitespace): New function. * cli/cli-utils.c (remove_trailing_whitespace): Likewise. PR c++/12273 * linespec.c (locate_first_half): Keep overload information, too. (decode_compound): Use a string to represent break characters to escape the loop. If P points to a break character, do not increment it. For C++ and Java, keep overload information and relevant keywords. If we cannot find a symbol, search the minimal symbols. PR c++/11734 * linespec.c (decode_compound): Rename SAVED_ARG to THE_REAL_SAVED_ARG. Make a copy of THE_REAL_SAVED_ARG in SAVED_ARG and strip single-quotes. Pass a valid block to lookup_symbol. (lookup_prefix_sym): Likewise. (find_method): Construct search name based on SYM_CLASS instead of SAVED_ARG. * psymtab.c (lookup_partial_symbol): Add language parameter. (lookup_symbol_aux_psymtabs): Likewise. Don't assume that the psymtab we found was the right one. Search for the desired symbol in the symtab to be certain. (psymtab_search_name): New function. (lookup_partial_symbol): Use psymtab_search_name. Add language parameter. (read_symtabs_for_function): Add language parameter and pass to lookup_partial_symbol. (find_symbol_file_from_partial): Likewise.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog39
-rw-r--r--gdb/cli/cli-utils.c11
-rw-r--r--gdb/cli/cli-utils.h4
-rw-r--r--gdb/linespec.c196
-rw-r--r--gdb/psymtab.c79
5 files changed, 280 insertions, 49 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 2bddd4a..5827164 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,42 @@
+2011-03-16 Keith Seitz <keiths@redhat.com>
+
+ * linespec.c (find_methods): Canonicalize NAME before looking
+ up the symbol.
+ (name_end): New function.
+ (keep_name_info): New function.
+ (decode_line_1): Use keep_name_info.
+ (decode_compound): Likewise.
+ * cli/cli-utils.h (remove_trailing_whitespace): New function.
+ * cli/cli-utils.c (remove_trailing_whitespace): Likewise.
+
+ PR c++/12273
+ * linespec.c (locate_first_half): Keep overload information, too.
+ (decode_compound): Use a string to represent break characters
+ to escape the loop.
+ If P points to a break character, do not increment it.
+ For C++ and Java, keep overload information and relevant keywords.
+ If we cannot find a symbol, search the minimal symbols.
+
+ PR c++/11734
+ * linespec.c (decode_compound): Rename SAVED_ARG to
+ THE_REAL_SAVED_ARG.
+ Make a copy of THE_REAL_SAVED_ARG in SAVED_ARG and strip
+ single-quotes.
+ Pass a valid block to lookup_symbol.
+ (lookup_prefix_sym): Likewise.
+ (find_method): Construct search name based on SYM_CLASS instead
+ of SAVED_ARG.
+ * psymtab.c (lookup_partial_symbol): Add language parameter.
+ (lookup_symbol_aux_psymtabs): Likewise.
+ Don't assume that the psymtab we found was the right one. Search
+ for the desired symbol in the symtab to be certain.
+ (psymtab_search_name): New function.
+ (lookup_partial_symbol): Use psymtab_search_name.
+ Add language parameter.
+ (read_symtabs_for_function): Add language parameter and pass to
+ lookup_partial_symbol.
+ (find_symbol_file_from_partial): Likewise.
+
2011-03-16 Paul Pluzhnikov <ppluzhnikov@google.com>
PR gdb/12528
diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c
index 2cce068..62a2f12 100644
--- a/gdb/cli/cli-utils.c
+++ b/gdb/cli/cli-utils.c
@@ -234,3 +234,14 @@ skip_to_space (char *chp)
chp++;
return chp;
}
+
+/* See documentation in cli-utils.h. */
+
+char *
+remove_trailing_whitespace (const char *start, char *s)
+{
+ while (s > start && isspace (*(s - 1)))
+ --s;
+
+ return s;
+}
diff --git a/gdb/cli/cli-utils.h b/gdb/cli/cli-utils.h
index 2954c46..8a6e5b3 100644
--- a/gdb/cli/cli-utils.h
+++ b/gdb/cli/cli-utils.h
@@ -99,4 +99,8 @@ extern char *skip_spaces (char *inp);
extern char *skip_to_space (char *inp);
+/* Reverse S to the last non-whitespace character without skipping past
+ START. */
+
+extern char *remove_trailing_whitespace (const char *start, char *s);
#endif /* CLI_UTILS_H */
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 68859a8..3959402 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -41,6 +41,8 @@
#include "mi/mi-cmds.h"
#include "target.h"
#include "arch-utils.h"
+#include <ctype.h>
+#include "cli/cli-utils.h"
/* We share this one with symtab.c, but it is not exported widely. */
@@ -213,6 +215,19 @@ find_methods (struct type *t, char *name, enum language language,
int i1 = 0;
int ibase;
char *class_name = type_name_no_tag (t);
+ struct cleanup *cleanup;
+ char *canon;
+
+ /* NAME is typed by the user: it needs to be canonicalized before
+ passing to lookup_symbol. */
+ canon = cp_canonicalize_string (name);
+ if (canon != NULL)
+ {
+ name = canon;
+ cleanup = make_cleanup (xfree, name);
+ }
+ else
+ cleanup = make_cleanup (null_cleanup, NULL);
/* Ignore this class if it doesn't have a name. This is ugly, but
unless we figure out how to get the physname without the name of
@@ -275,6 +290,7 @@ find_methods (struct type *t, char *name, enum language language,
i1 += find_methods (TYPE_BASECLASS (t, ibase), name,
language, sym_arr + i1);
+ do_cleanups (cleanup);
return i1;
}
@@ -663,6 +679,65 @@ find_method_overload_end (char *p)
return p;
}
+
+/* Does P point to a sequence of characters which implies the end
+ of a name? Terminals include "if" and "thread" clauses. */
+
+static int
+name_end (char *p)
+{
+ while (isspace (*p))
+ ++p;
+ if (*p == 'i' && p[1] == 'f'
+ && (isspace (p[2]) || p[2] == '\0' || p[2] == '('))
+ return 1;
+
+ if (strncmp (p, "thread", 6) == 0
+ && (isspace (p[6]) || p[6] == '\0'))
+ return 1;
+
+ return 0;
+}
+
+/* Keep important information used when looking up a name. This includes
+ template parameters, overload information, and important keywords. */
+
+static char *
+keep_name_info (char *ptr)
+{
+ char *p = ptr;
+ char *start = ptr;
+
+ /* Keep any template parameters. */
+ if (name_end (ptr))
+ return remove_trailing_whitespace (start, ptr);
+
+ while (isspace (*p))
+ ++p;
+ if (*p == '<')
+ ptr = p = find_template_name_end (ptr);
+
+ if (name_end (ptr))
+ return remove_trailing_whitespace (start, ptr);
+
+ /* Keep method overload information. */
+ if (*p == '(')
+ ptr = p = find_method_overload_end (p);
+
+ if (name_end (ptr))
+ return remove_trailing_whitespace (start, ptr);
+
+ /* Keep important keywords. */
+ while (isspace (*p))
+ ++p;
+ if (strncmp (p, "const", 5) == 0
+ && (isspace (p[5]) || p[5] == '\0'
+ || strchr (get_gdb_completer_quote_characters (), p[5]) != NULL))
+ ptr = p = p + 5;
+
+ return remove_trailing_whitespace (start, ptr);
+}
+
/* The parser of linespec itself. */
@@ -871,17 +946,8 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
p = skip_quoted (*argptr);
}
- /* Keep any template parameters. */
- if (*p == '<')
- p = find_template_name_end (p);
-
- /* Keep method overload information. */
- if (*p == '(')
- p = find_method_overload_end (p);
-
- /* Make sure we keep important kewords like "const". */
- if (strncmp (p, " const", 6) == 0)
- p += 6;
+ /* Keep any important naming information. */
+ p = keep_name_info (p);
copy = (char *) alloca (p - *argptr + 1);
memcpy (copy, *argptr, p - *argptr);
@@ -1057,6 +1123,10 @@ locate_first_half (char **argptr, int *is_quote_enclosed)
error (_("malformed template specification in command"));
p = temp_end;
}
+
+ if (p[0] == '(')
+ p = find_method_overload_end (p);
+
/* Check for a colon and a plus or minus and a [ (which
indicates an Objective-C method). */
if (is_objc_method_format (p))
@@ -1224,7 +1294,7 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab,
static struct symtabs_and_lines
decode_compound (char **argptr, int funfirstline, char ***canonical,
- char *saved_arg, char *p, int *not_found_ptr)
+ char *the_real_saved_arg, char *p, int *not_found_ptr)
{
struct symtabs_and_lines values;
char *p2;
@@ -1235,6 +1305,23 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
struct symbol *sym_class;
struct type *t;
char *saved_java_argptr = NULL;
+ char *saved_arg;
+
+ /* If the user specified any completer quote characters in the input,
+ strip them. They are superfluous. */
+ saved_arg = alloca (strlen (the_real_saved_arg) + 1);
+ {
+ char *dst = saved_arg;
+ char *src = the_real_saved_arg;
+ char *quotes = get_gdb_completer_quote_characters ();
+ while (*src != '\0')
+ {
+ if (strchr (quotes, *src) == NULL)
+ *dst++ = *src;
+ ++src;
+ }
+ *dst = '\0';
+ }
/* First check for "global" namespace specification, of the form
"::foo". If found, skip over the colons and jump to normal
@@ -1251,8 +1338,10 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
find_method.
2) AAA::inA isn't the name of a class. In that case, either the
- user made a typo or AAA::inA is the name of a namespace.
- Either way, we just look up AAA::inA::fun with lookup_symbol.
+ user made a typo, AAA::inA is the name of a namespace, or it is
+ the name of a minimal symbol.
+ We just look up AAA::inA::fun with lookup_symbol. If that fails,
+ try lookup_minimal_symbol.
Thus, our first task is to find everything before the last set of
double-colons and figure out if it's the name of a class. So we
@@ -1273,6 +1362,8 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
while (1)
{
+ static char *break_characters = " \t(";
+
/* Move pointer up to next possible class/namespace token. */
p = p2 + 1; /* Restart with old value +1. */
@@ -1283,8 +1374,9 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
/* PASS2: p2->"::fun", p->":fun" */
/* Move pointer ahead to next double-colon. */
- while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'')
- && (*p != '('))
+ while (*p
+ && strchr (break_characters, *p) == NULL
+ && strchr (get_gdb_completer_quote_characters (), *p) == NULL)
{
if (current_language->la_language == language_cplus)
p += cp_validate_operator (p);
@@ -1308,9 +1400,12 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
else if ((p[0] == ':') && (p[1] == ':'))
break; /* Found double-colon. */
else
- /* PASS2: We'll keep getting here, until p->"", at which point
- we exit this loop. */
- p++;
+ {
+ /* PASS2: We'll keep getting here, until P points to one of the
+ break characters, at which point we exit this loop. */
+ if (*p && strchr (break_characters, *p) == NULL)
+ p++;
+ }
}
if (*p != ':')
@@ -1319,7 +1414,7 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
unsuccessfully all the components of the
string, and p->""(PASS2). */
- /* We get here if p points to ' ', '\t', '\'', "::" or ""(i.e
+ /* We get here if p points to one of the break characters or "" (i.e.,
string ended). */
/* Save restart for next time around. */
p2 = p;
@@ -1379,18 +1474,8 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
p += cp_validate_operator (p - 8) - 8;
}
- /* Keep any template parameters. */
- if (*p == '<')
- p = find_template_name_end (p);
-
- /* Keep method overload information. */
- a = strchr (p, '(');
- if (a != NULL)
- p = find_method_overload_end (a);
-
- /* Make sure we keep important kewords like "const". */
- if (strncmp (p, " const", 6) == 0)
- p += 6;
+ /* Keep any important naming information. */
+ p = keep_name_info (p);
/* Java may append typenames, so assume that if there is
anything else left in *argptr, it must be a typename. */
@@ -1470,6 +1555,10 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
/* We couldn't find a class, so we're in case 2 above. We check the
entire name as a symbol instead. */
+ if (current_language->la_language == language_cplus
+ || current_language->la_language == language_java)
+ p = keep_name_info (p);
+
copy = (char *) alloca (p - saved_arg2 + 1);
memcpy (copy, saved_arg2, p - saved_arg2);
/* Note: if is_quoted should be true, we snuff out quote here
@@ -1479,15 +1568,24 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
*argptr = (*p == '\'') ? p + 1 : p;
/* Look up entire name. */
- sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0);
+ sym = lookup_symbol (copy, get_selected_block (0), VAR_DOMAIN, 0);
if (sym)
return symbol_found (funfirstline, canonical, copy, sym, NULL);
+ else
+ {
+ struct minimal_symbol *msym;
+
+ /* Couldn't find any interpretation as classes/namespaces. As a last
+ resort, try the minimal symbol tables. */
+ msym = lookup_minimal_symbol (copy, NULL, NULL);
+ if (msym != NULL)
+ return minsym_found (funfirstline, msym);
+ }
- /* Couldn't find any interpretation as classes/namespaces, so give
- up. The quotes are important if copy is empty. */
+ /* Couldn't find a minimal symbol, either, so give up. */
if (not_found_ptr)
*not_found_ptr = 1;
- cplusplus_error (saved_arg,
+ cplusplus_error (the_real_saved_arg,
"Can't find member of namespace, "
"class, struct, or union named \"%s\"\n",
copy);
@@ -1526,7 +1624,7 @@ lookup_prefix_sym (char **argptr, char *p)
/* At this point p1->"::inA::fun", p->"inA::fun" copy->"AAA",
argptr->"inA::fun". */
- sym = lookup_symbol (copy, 0, STRUCT_DOMAIN, 0);
+ sym = lookup_symbol (copy, get_selected_block (0), STRUCT_DOMAIN, 0);
if (sym == NULL)
{
/* Typedefs are in VAR_DOMAIN so the above symbol lookup will
@@ -1594,20 +1692,32 @@ find_method (int funfirstline, char ***canonical, char *saved_arg,
/* If we were given a specific overload instance, use that
(or error if no matches were found). Otherwise ask the user
which one to use. */
- if (strchr (saved_arg, '(') != NULL)
+ if (strchr (copy, '('))
{
int i;
- char *name = saved_arg;
- char *canon = cp_canonicalize_string (name);
+ char *name;
+ char *canon;
struct cleanup *cleanup;
+ /* Construct the proper search name based on SYM_CLASS and COPY.
+ SAVED_ARG may contain a valid name, but that name might not be
+ what is actually stored in the symbol table. For example,
+ if SAVED_ARG (and SYM_CLASS) were found via an import
+ ("using namespace" in C++), then the physname of
+ SYM_CLASS ("A::myclass") may not be the same as SAVED_ARG
+ ("myclass"). */
+ name = xmalloc (strlen (SYMBOL_NATURAL_NAME (sym_class))
+ + 2 /* "::" */ + strlen (copy) + 1);
+ strcpy (name, SYMBOL_NATURAL_NAME (sym_class));
+ strcat (name, "::");
+ strcat (name, copy);
+ canon = cp_canonicalize_string (name);
if (canon != NULL)
{
+ xfree (name);
name = canon;
- cleanup = make_cleanup (xfree, canon);
}
- else
- cleanup = make_cleanup (null_cleanup, NULL);
+ cleanup = make_cleanup (xfree, name);
for (i = 0; i < i1; ++i)
{
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index eeae03b..edd476e 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -33,6 +33,8 @@
#include "readline/readline.h"
#include "gdb_regex.h"
#include "dictionary.h"
+#include "language.h"
+#include "cp-support.h"
#ifndef DEV_TTY
#define DEV_TTY "/dev/tty"
@@ -480,7 +482,26 @@ lookup_symbol_aux_psymtabs (struct objfile *objfile,
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
{
if (!ps->readin && lookup_partial_symbol (ps, name, psymtab_index, domain))
- return PSYMTAB_TO_SYMTAB (ps);
+ {
+ struct symbol *sym = NULL;
+ struct symtab *stab = PSYMTAB_TO_SYMTAB (ps);
+
+ /* Some caution must be observed with overloaded functions
+ and methods, since the psymtab will not contain any overload
+ information (but NAME might contain it). */
+ if (stab->primary)
+ {
+ struct blockvector *bv = BLOCKVECTOR (stab);
+ struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
+
+ sym = lookup_block_symbol (block, name, domain);
+ }
+
+ if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
+ return stab;
+
+ /* Keep looking through other psymtabs. */
+ }
}
return NULL;
@@ -573,6 +594,39 @@ pre_expand_symtabs_matching_psymtabs (struct objfile *objfile,
/* Nothing. */
}
+/* Returns the name used to search psymtabs. Unlike symtabs, psymtabs do
+ not contain any method/function instance information (since this would
+ force reading type information while reading psymtabs). Therefore,
+ if NAME contains overload information, it must be stripped before searching
+ psymtabs.
+
+ The caller is responsible for freeing the return result. */
+
+static char *
+psymtab_search_name (const char *name)
+{
+ switch (current_language->la_language)
+ {
+ case language_cplus:
+ case language_java:
+ {
+ if (strchr (name, '('))
+ {
+ char *ret = cp_remove_params (name);
+
+ if (ret)
+ return ret;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return xstrdup (name);
+}
+
/* Look, in partial_symtab PST, for symbol whose natural name is NAME.
Check the global symbols if GLOBAL, the static symbols if not. */
@@ -584,11 +638,16 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
struct partial_symbol **top, **real_top, **bottom, **center;
int length = (global ? pst->n_global_syms : pst->n_static_syms);
int do_linear_search = 1;
+ char *search_name;
+ struct cleanup *cleanup;
if (length == 0)
{
return (NULL);
}
+
+ search_name = psymtab_search_name (name);
+ cleanup = make_cleanup (xfree, search_name);
start = (global ?
pst->objfile->global_psymbols.list + pst->globals_offset :
pst->objfile->static_psymbols.list + pst->statics_offset);
@@ -617,7 +676,8 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
{
do_linear_search = 1;
}
- if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center), name) >= 0)
+ if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center),
+ search_name) >= 0)
{
top = center;
}
@@ -631,11 +691,14 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
_("failed internal consistency check"));
while (top <= real_top
- && SYMBOL_MATCHES_SEARCH_NAME (*top, name))
+ && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
{
if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
SYMBOL_DOMAIN (*top), domain))
- return (*top);
+ {
+ do_cleanups (cleanup);
+ return (*top);
+ }
top++;
}
}
@@ -649,11 +712,15 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
{
if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
SYMBOL_DOMAIN (*psym), domain)
- && SYMBOL_MATCHES_SEARCH_NAME (*psym, name))
- return (*psym);
+ && SYMBOL_MATCHES_SEARCH_NAME (*psym, search_name))
+ {
+ do_cleanups (cleanup);
+ return (*psym);
+ }
}
}
+ do_cleanups (cleanup);
return (NULL);
}