[patch 1/3] revert physname part (b) [Re: [RFA] c++/11734 revisited]

Jan Kratochvil
2011-02-06T22:46:17Z

Hi Keith,

[patch 1/3] is revert of the parts (b)+(c).

Jan

--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -40,7 +40,6 @@
#include "interps.h"
#include "mi/mi-cmds.h"
#include "target.h"
-#include "arch-utils.h"

/* We share this one with symtab.c, but it is not exported widely. */

@@ -51,6 +50,8 @@ extern char *operator_chars (char *, char **);
static void initialize_defaults (struct symtab **default_symtab,
int *default_line);

+static void set_flags (char *arg, int *is_quoted, char **paren_pointer);
+
static struct symtabs_and_lines decode_indirect (char **argptr);

static char *locate_first_half (char **argptr, int *is_quote_enclosed);
@@ -632,37 +633,6 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline,
discard_cleanups (old_chain);
return return_values;
}
-
-/* A helper function for decode_line_1 and friends which skips P
- past any method overload information at the beginning of P, e.g.,
- "(const struct foo *)".
-
- This function assumes that P has already been validated to contain
- overload information, and it will assert if *P != '('. */
-static char *
-find_method_overload_end (char *p)
-{
- int depth = 0;
-
- gdb_assert (*p == '(');
-
- while (*p)
- {
- if (*p == '(')
- ++depth;
- else if (*p == ')')
- {
- if (--depth == 0)
- {
- ++p;
- break;
- }
- }
- ++p;
- }
-
- return p;
-}
\f
/* The parser of linespec itself. */

@@ -724,6 +694,9 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
struct symtab *file_symtab = NULL;

char *copy;
+ /* This is NULL if there are no parens in *ARGPTR, or a pointer to
+ the closing parenthesis if there are parens. */
+ char *paren_pointer;
/* This says whether or not something in *ARGPTR is quoted with
completer_quotes (i.e. with single quotes). */
int is_quoted;
@@ -748,9 +721,12 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
if (**argptr == '*')
return decode_indirect (argptr);

- is_quoted = (*argptr
- && strchr (get_gdb_completer_quote_characters (),
- **argptr) != NULL);
+ /* Set various flags. 'paren_pointer' is important for overload
+ checking, where we allow things like:
+ (gdb) break c::f(int)
+ */
+
+ set_flags (*argptr, &is_quoted, &paren_pointer);
if (is_quoted)
end_quote = skip_quoted (*argptr);

@@ -768,7 +744,10 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
/* Check if this is an Objective-C method (anything that starts with
a '+' or '-' and a '['). */
if (is_objc_method_format (p))
- is_objc_method = 1;
+ {
+ is_objc_method = 1;
+ paren_pointer = NULL; /* Just a category name. Ignore it. */
+ }

/* Check if the symbol could be an Objective-C selector. */

@@ -794,33 +773,63 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,

if (p[0] == '.' || p[1] == ':')
{
- struct symtabs_and_lines values;
-
- if (is_quote_enclosed)
- ++saved_arg;
- values = decode_compound (argptr, funfirstline, canonical,
+ if (paren_pointer == NULL)
+ return decode_compound (argptr, funfirstline, canonical,
saved_arg, p, not_found_ptr);
- if (is_quoted && **argptr == '\'')
- *argptr = *argptr + 1;
- return values;
+ /* 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
+ breaks the command line, though, whenever the passed
+ name is of the form ClassName::Method. This bit of code
+ singles out the class name, and if funfirstline is set (for
+ example, you are setting a breakpoint at this function),
+ you get an error. This did not occur with earlier
+ verions, so I am ifdef'ing this out. 3/29/99 */
+ else
+ {
+ /* Check if what we have till now is a symbol name */

- /* Check for single quotes on the non-filename part. */
- if (!is_quoted)
+ /* We may be looking at a template instantiation such
+ as "foo<int>". Check here whether we know about it,
+ instead of falling through to the code below which
+ handles ordinary function names, because that code
+ doesn't like seeing '<' and '>' in a name -- the
+ skip_quoted call doesn't go past them. So see if we
+ can figure it out right now. */
+
+ copy = (char *) alloca (p - *argptr + 1);
+ memcpy (copy, *argptr, p - *argptr);
+ copy[p - *argptr] = '\000';
+ sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0);
+ if (sym)
{
- is_quoted = (**argptr
- && strchr (get_gdb_completer_quote_characters (),
- **argptr) != NULL);
- if (is_quoted)
- end_quote = skip_quoted (*argptr);
+ *argptr = (*p == '\'') ? p + 1 : p;
+ return symbol_found (funfirstline, canonical, copy, sym, NULL);
}
+ /* Otherwise fall out from here and go to file/line spec
+ processing, etc. */
}
+#endif

/* file_symtab is specified file's symtab, or 0 if no file specified.
arg no longer contains the file name. */
@@ -866,6 +875,10 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
/* allow word separators in method names for Obj-C. */
p = skip_quoted_chars (*argptr, NULL, "");
}
+ else if (paren_pointer != NULL)
+ {
+ p = paren_pointer + 1;
+ }
else
{
p = skip_quoted (*argptr);
@@ -875,14 +888,6 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
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;
-
copy = (char *) alloca (p - *argptr + 1);
memcpy (copy, *argptr, p - *argptr);
copy[p - *argptr] = '\0';
@@ -940,9 +945,10 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
function is passed ARGPTR as an argument, it modifies what ARGPTR
points to; typically, it advances *ARGPTR past whatever substring
it has just looked at. (If it doesn't modify *ARGPTR, then the
- function gets passed *ARGPTR instead, which is then called ARG.)
- Also, functions that return a struct symtabs_and_lines may modify
- CANONICAL, as in the description of decode_line_1.
+ function gets passed *ARGPTR instead, which is then called ARG: see
+ set_flags, for example.) Also, functions that return a struct
+ symtabs_and_lines may modify CANONICAL, as in the description of
+ decode_line_1.

If a function returns a struct symtabs_and_lines, then that struct
will immediately make its way up the call chain to be returned by
@@ -969,6 +975,44 @@ initialize_defaults (struct symtab **default_symtab, int *default_line)
}
}

+static void
+set_flags (char *arg, int *is_quoted, char **paren_pointer)
+{
+ char *ii;
+ int has_if = 0;
+
+ /* 'has_if' is for the syntax:
+ (gdb) break foo if (a==b)
+ */
+ if ((ii = strstr (arg, " if ")) != NULL ||
+ (ii = strstr (arg, "\tif ")) != NULL ||
+ (ii = strstr (arg, " if\t")) != NULL ||
+ (ii = strstr (arg, "\tif\t")) != NULL ||
+ (ii = strstr (arg, " if(")) != NULL ||
+ (ii = strstr (arg, "\tif( ")) != NULL)
+ has_if = 1;
+ /* Temporarily zap out "if (condition)" to not confuse the
+ parenthesis-checking code below. This is undone below. Do not
+ change ii!! */
+ if (has_if)
+ {
+ *ii = '\0';
+ }
+
+ *is_quoted = (*arg
+ && strchr (get_gdb_completer_quote_characters (),
+ *arg) != NULL);
+
+ *paren_pointer = strchr (arg, '(');
+ if (*paren_pointer != NULL)
+ *paren_pointer = strrchr (*paren_pointer, ')');
+
+ /* Now that we're safely past the paren_pointer check, put back " if
+ (condition)" so outer layers can see it. */
+ if (has_if)
+ *ii = ' ';
+}
+
\f

/* Decode arg of the form *PC. */
@@ -1076,9 +1120,8 @@ locate_first_half (char **argptr, int *is_quote_enclosed)
if (p[0] == '.' && strchr (p, ':') == NULL)
{
/* Java qualified method. Find the *last* '.', since the
- others are package qualifiers. Stop at any open parenthesis
- which might provide overload information. */
- for (p1 = p; *p1 && *p1 != '('; p1++)
+ others are package qualifiers. */
+ for (p1 = p; *p1; p1++)
{
if (*p1 == '.')
p = p1;
@@ -1236,7 +1279,6 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
char *copy;
struct symbol *sym_class;
struct type *t;
- char *saved_java_argptr = NULL;

/* First check for "global" namespace specification, of the form
"::foo". If found, skip over the colons and jump to normal
@@ -1285,8 +1327,7 @@ 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 && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\''))
{
if (current_language->la_language == language_cplus)
p += cp_validate_operator (p);
@@ -1364,11 +1405,9 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
else
{
/* At this point argptr->"fun". */
- char *a;

p = *argptr;
- while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':'
- && *p != '(')
+ while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':')
p++;
/* At this point p->"". String ended. */
/* Nope, C++ operators could have spaces in them
@@ -1380,43 +1419,6 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
/* The above loop has already swallowed "operator". */
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;
-
- /* Java may append typenames, so assume that if there is
- anything else left in *argptr, it must be a typename. */
- if (*p && current_language->la_language == language_java)
- {
- struct type *type;
-
- p2 = p;
- while (*p2)
- ++p2;
- copy = (char *) alloca (p2 - p + 1);
- memcpy (copy, p, p2 - p);
- copy[p2 - p] = '\0';
- type = lookup_typename (current_language, get_current_arch (),
- copy, NULL, 1);
- if (type != NULL)
- {
- /* Save the location of this just in case this
- method/type combination isn't actually defined.
- It will be checked later. */
- saved_java_argptr = p;
- p = p2;
- }
- }
}

/* Allocate our own copy of the substring between argptr and
@@ -1445,27 +1447,9 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
here, we return. If not, and we are at the and of the string,
we'll lookup the whole string in the symbol tables. */

- values = find_method (funfirstline, canonical, saved_arg,
- copy, t, sym_class, not_found_ptr);
- if (saved_java_argptr != NULL && values.nelts == 1)
- {
- /* The user specified a specific return type for a java method.
- Double-check that it really is the one the user specified.
- [This is a necessary evil because strcmp_iw_ordered stops
- comparisons too prematurely.] */
- sym = find_pc_sect_function (values.sals[0].pc,
- values.sals[0].section);
- /* We just found a SAL, we had better be able to go backwards! */
- gdb_assert (sym != NULL);
- if (strcmp_iw (SYMBOL_LINKAGE_NAME (sym), saved_arg) != 0)
- {
- xfree (values.sals);
- error (_("the class `%s' does not have "
- "any method instance named %s"),
- SYMBOL_PRINT_NAME (sym_class), copy);
- }
- }
- return values;
+ return find_method (funfirstline, canonical, saved_arg,
+ copy, t, sym_class, not_found_ptr);
+
} /* End if symbol found. */

@@ -1593,43 +1577,8 @@ find_method (int funfirstline, char ***canonical, char *saved_arg,
}
if (i1 > 0)
{
- /* 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)
- {
- int i;
- char *name = saved_arg;
- char *canon = cp_canonicalize_string (name);
- struct cleanup *cleanup;
-
- if (canon != NULL)
- {
- name = canon;
- cleanup = make_cleanup (xfree, canon);
- }
- else
- cleanup = make_cleanup (null_cleanup, NULL);
-
- for (i = 0; i < i1; ++i)
- {
- if (strcmp_iw (name, SYMBOL_LINKAGE_NAME (sym_arr[i])) == 0)
- {
- values.sals = (struct symtab_and_line *)
- xmalloc (sizeof (struct symtab_and_line));
- values.nelts = 1;
- values.sals[0] = find_function_start_sal (sym_arr[i],
- funfirstline);
- do_cleanups (cleanup);
- return values;
- }
- }
-
- error (_("the class `%s' does not have "
- "any method instance named %s"),
- SYMBOL_PRINT_NAME (sym_class), copy);
- }
-
+ /* There is more than one field with that name
+ (overloaded). Ask the user which one to use. */
return decode_line_2 (sym_arr, i1, funfirstline, canonical);
}
else