#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. */
-
-extern char *operator_chars (char *, char **);
+#include "filenames.h"
/* Prototypes for local functions. */
/* NAME is typed by the user: it needs to be canonicalized before
passing to lookup_symbol. */
- canon = cp_canonicalize_string (name);
+ canon = cp_canonicalize_string_no_typedefs (name);
if (canon != NULL)
{
name = canon;
return return_values;
}
+/* Valid delimiters for linespec keywords "if", "thread" or "task". */
+
+static int
+is_linespec_boundary (char c)
+{
+ return c == ' ' || c == '\t' || c == '\0' || c == ',';
+}
+
/* 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 *)".
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. */
+ template parameters, overload information, and important keywords, including
+ the possible Java trailing type. */
static char *
-keep_name_info (char *ptr)
+keep_name_info (char *p, int on_boundary)
{
- char *p = ptr;
- char *start = ptr;
+ const char *quotes = get_gdb_completer_quote_characters ();
+ char *saved_p = p;
+ int nest = 0;
- /* Keep any template parameters. */
- if (name_end (ptr))
- return remove_trailing_whitespace (start, ptr);
+ while (*p)
+ {
+ if (strchr (quotes, *p))
+ break;
- p = skip_spaces (p);
- if (*p == '<')
- ptr = p = find_template_name_end (ptr);
+ if (*p == ',' && !nest)
+ break;
- if (name_end (ptr))
- return remove_trailing_whitespace (start, ptr);
+ if (on_boundary && !nest)
+ {
+ const char *const words[] = { "if", "thread", "task" };
+ int wordi;
- /* Keep method overload information. */
- if (*p == '(')
- ptr = p = find_method_overload_end (p);
+ for (wordi = 0; wordi < ARRAY_SIZE (words); wordi++)
+ if (strncmp (p, words[wordi], strlen (words[wordi])) == 0
+ && is_linespec_boundary (p[strlen (words[wordi])]))
+ break;
+ if (wordi < ARRAY_SIZE (words))
+ break;
+ }
- if (name_end (ptr))
- return remove_trailing_whitespace (start, ptr);
+ if (*p == '(' || *p == '<' || *p == '[')
+ nest++;
+ else if ((*p == ')' || *p == '>' || *p == ']') && nest > 0)
+ nest--;
- /* Keep important keywords. */
- while (1)
- {
- char *quotes = get_gdb_completer_quote_characters ();
- p = skip_spaces (p);
- if (strncmp (p, "const", 5) == 0
- && (isspace (p[5]) || p[5] == '\0'
- || strchr (quotes, p[5]) != NULL))
- ptr = p = p + 5;
- else if (strncmp (p, "volatile", 8) == 0
- && (isspace (p[8]) || p[8] == '\0'
- || strchr (quotes, p[8]) != NULL))
- ptr = p = p + 8;
- else
- break;
+ p++;
+
+ /* The ',' check could fail on "operator ,". */
+ p += cp_validate_operator (p);
+
+ on_boundary = is_linespec_boundary (p[-1]);
}
- return remove_trailing_whitespace (start, ptr);
+ while (p > saved_p && is_linespec_boundary (p[-1]))
+ p--;
+
+ return p;
}
\f
/* This says whether or not something in *ARGPTR is quoted with
completer_quotes (i.e. with single quotes). */
int is_quoted;
- /* Is *ARGPTR is enclosed in double quotes? */
+ /* Is *ARGPTR enclosed in double quotes? */
int is_quote_enclosed;
int is_objc_method = 0;
char *saved_arg = *argptr;
if (is_quote_enclosed)
++saved_arg;
+ /* Initialize it just to avoid a GCC false warning. */
+ memset (&values, 0, sizeof (values));
+
TRY_CATCH (ex, RETURN_MASK_ERROR)
{
values = decode_compound (argptr, funfirstline, canonical,
}
/* Keep any important naming information. */
- p = keep_name_info (p);
+ p = keep_name_info (p, p == saved_arg || is_linespec_boundary (p[-1]));
copy = (char *) alloca (p - *argptr + 1);
memcpy (copy, *argptr, p - *argptr);
++p;
}
}
+
+
+ /* Check for a drive letter in the filename. This is done on all hosts
+ to capture cross-compilation environments. On Unixen, directory
+ separators are illegal in filenames, so if the user enters "e:/foo.c",
+ he is referring to a directory named "e:" and a source file named
+ "foo.c", and we still want to keep these two pieces together. */
+ if (isalpha (p[0]) && p[1] == ':' && IS_DIR_SEPARATOR (p[2]))
+ p += 3;
+
for (; *p; p++)
{
if (p[0] == '<')
char *the_real_saved_arg, char *p)
{
struct symtabs_and_lines values;
- char *p2;
+ char *p2, *name, *canon;
char *saved_arg2 = *argptr;
char *temp_end;
struct symbol *sym;
char *copy;
struct symbol *sym_class;
struct type *t;
- char *saved_java_argptr = NULL;
char *saved_arg;
+ struct cleanup *cleanup;
/* If the user specified any completer quote characters in the input,
strip them. They are superfluous. */
}
/* 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. */
- 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;
- }
- }
+ p = keep_name_info (p, 1);
}
/* Allocate our own copy of the substring between argptr and
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, file_symtab);
- 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, file_symtab);
} /* End if symbol found. */
/* We couldn't find a class, so we're in case 2 above. We check the
entire name as a symbol instead. */
- p = keep_name_info (p);
+ p = keep_name_info (p, 1);
copy = (char *) alloca (p - saved_arg2 + 1);
memcpy (copy, saved_arg2, p - saved_arg2);
*argptr = (*p == '\'') ? p + 1 : p;
/* Look up entire name. */
- sym = lookup_symbol (copy, get_selected_block (0), VAR_DOMAIN, 0);
+ name = copy;
+
+ cleanup = make_cleanup (null_cleanup, NULL);
+ canon = cp_canonicalize_string_no_typedefs (copy);
+ if (canon != NULL)
+ {
+ name = canon;
+ make_cleanup (xfree, name);
+ }
+
+ sym = lookup_symbol (name, get_selected_block (0), VAR_DOMAIN, 0);
+ do_cleanups (cleanup);
if (sym)
return symbol_found (funfirstline, canonical, copy, sym, NULL, NULL);
else
i1 = find_methods (t, copy, SYMBOL_LANGUAGE (sym_class), sym_arr,
file_symtab);
- if (i1 == 1)
+ /* If we were given a specific overload instance in COPY, defer the field
+ acceptance till the strcmp_iw verification below, even if we found just
+ a single field with that name. */
+ if (i1 == 1 && strchr (copy, '(') == NULL)
{
/* There is exactly one field with that name. */
sym = sym_arr[0];
strcpy (name, SYMBOL_NATURAL_NAME (sym_class));
strcat (name, "::");
strcat (name, copy);
- canon = cp_canonicalize_string (name);
+ canon = cp_canonicalize_string_no_typedefs (name);
if (canon != NULL)
{
xfree (name);
}
/* Discard the file name from the arg. */
+ if (*p1 == '\0')
+ return file_symtab;
p = p1 + 1;
while (*p == ' ' || *p == '\t')
p++;
struct linespec_result *canonical,
struct symtab *file_symtab)
{
+ char *name, *canon;
struct symbol *sym;
+ struct cleanup *cleanup;
struct minimal_symbol *msymbol;
- sym = lookup_symbol (copy, get_search_block (file_symtab),
- VAR_DOMAIN, 0);
+ name = copy;
+ cleanup = make_cleanup (null_cleanup, NULL);
+ canon = cp_canonicalize_string_no_typedefs (copy);
+ if (canon != NULL)
+ {
+ name = canon;
+ make_cleanup (xfree, name);
+ }
+
+ sym = lookup_symbol (name, get_search_block (file_symtab), VAR_DOMAIN, 0);
if (sym != NULL)
- return symbol_found (funfirstline, canonical, copy, sym, file_symtab, NULL);
+ {
+ do_cleanups (cleanup);
+ return symbol_found (funfirstline, canonical, copy, sym,
+ file_symtab, NULL);
+ }
- msymbol = lookup_minimal_symbol (copy, NULL, NULL);
+ msymbol = lookup_minimal_symbol (name, NULL, NULL);
+ do_cleanups (cleanup);
if (msymbol != NULL)
return minsym_found (funfirstline, msymbol);