scan_for_anonymous_namespaces (struct symbol *symbol)
{
const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
- const char *beginning;
- const char *end;
+ int old_index;
+ int new_index;
+ const char *len;
/* Start with a quick-and-dirty check for mention of "(anonymous
namespace)". */
if (!cp_is_anonymous (name, -1))
return;
- beginning = name;
- end = cp_find_first_component (beginning);
+ old_index = 0;
+ new_index = cp_find_first_component (name + old_index);
- while (*end == ':')
+ while (name[new_index] == ':')
{
- if ((end - beginning) == ANONYMOUS_NAMESPACE_LEN
- && strncmp (beginning, "(anonymous namespace)",
+ if ((new_index - old_index) == ANONYMOUS_NAMESPACE_LEN
+ && strncmp (name + old_index, "(anonymous namespace)",
ANONYMOUS_NAMESPACE_LEN) == 0)
{
/* We've found a component of the name that's an anonymous
by the previous component if there is one, or to the
global namespace if there isn't. */
add_using_directive (name,
- beginning == name ? 0 : beginning - name - 2,
- end - name);
+ old_index == 0 ? 0 : old_index - 2,
+ new_index);
}
/* The "+ 2" is for the "::". */
- beginning = end + 2;
- end = cp_find_first_component (beginning);
+ old_index = new_index + 2;
+ new_index = old_index + cp_find_first_component (name + old_index);
}
}
think that's a problem yet, but it will be. */
current = name;
- next = cp_find_first_component (current);
+ next = current + cp_find_first_component (current);
while (*next == ':')
{
current = next;
/* The '+ 2' is to skip the '::'. */
- next = cp_find_first_component (current + 2);
+ next = current + 2;
+ next += cp_find_first_component (next);
}
if (current == name)
block_set_scope (block, "", &objfile->symbol_obstack);
#define LENGTH_OF_OPERATOR 8
-const char *
-cp_find_first_component (const char *name)
+int
+cp_find_first_component (const char *const name)
{
/* Names like 'operator<<' screw up the recursion, so let's
special-case them. I _hope_ they can only occur at the start of
a component. */
+ int index = 0;
+
if (strncmp (name, "operator", LENGTH_OF_OPERATOR) == 0)
{
- name += LENGTH_OF_OPERATOR;
- switch (*name)
+ index += LENGTH_OF_OPERATOR;
+ switch (name[index])
{
case '<':
- if (name[1] == '<')
- name += 2;
+ if (name[index + 1] == '<')
+ index += 2;
else
- name += 1;
+ index += 1;
break;
case '>':
case '-':
- if (name[1] == '>')
- name +=2;
+ if (name[index + 1] == '>')
+ index += 2;
else
- name += 1;
+ index += 1;
break;
case '(':
- name += 2;
+ index += 2;
break;
default:
- name += 1;
+ index += 1;
break;
}
}
- for (;; ++name)
+ for (;; ++index)
{
- switch (*name)
+ switch (name[index])
{
case '<':
/* Template; eat it up. The calls to cp_first_component
should only return (I hope!) when they reach the '>'
terminating the component or a '::' between two
components. (Hence the '+ 2'.) */
- for (name = cp_find_first_component (name + 1);
- *name != '>';
- name = cp_find_first_component (name + 2))
- gdb_assert (*name == ':');
+ index += 1;
+ for (index += cp_find_first_component (name + index);
+ name[index] != '>';
+ index += cp_find_first_component (name + index))
+ {
+ gdb_assert (name[index] == ':');
+ index += 2;
+ }
break;
case '(':
/* Similar comment as to '<'. */
- for (name = cp_find_first_component (name + 1);
- *name != ')';
- name = cp_find_first_component (name + 2))
- gdb_assert (*name == ':');
+ index += 1;
+ for (index += cp_find_first_component (name + index);
+ name[index] != ')';
+ index += cp_find_first_component (name + index))
+ {
+ gdb_assert (name[index] == ':');
+ index += 2;
+ }
break;
case '>':
case ')':
case '\0':
case ':':
- return name;
+ return index;
default:
break;
}
{
if (name[len] == ':')
{
- const char *next_name = cp_find_first_component (name + len + 2);
- int done = check_possible_namespace_symbols_loop (name,
- next_name - name);
+ int done;
+ int next_len = len + 2;
+
+ next_len += cp_find_first_component (name + next_len);
+ done = check_possible_namespace_symbols_loop (name, next_len);
if (!done)
{
done = check_one_possible_namespace_symbol (name, len);
}
+
return done;
}
else
cp_check_possible_namespace_symbols (const char *name)
{
check_possible_namespace_symbols_loop (name,
- cp_find_first_component (name)
- - name);
+ cp_find_first_component (name));
}
/* Look for a symbol in possible_namespace_block named NAME. */
if (!full_name)
return NULL;
- for (next_component = cp_find_first_component (previous_component);
+ for (next_component = (previous_component
+ + cp_find_first_component (previous_component));
*next_component == ':';
- next_component = cp_find_first_component (previous_component))
+ next_component = (previous_component
+ + cp_find_first_component (previous_component)))
{
/* Skip '::'. */
previous_component = next_component + 2;
#include "cp-abi.h"
#include "block.h"
#include "parser-defs.h"
+#include "cp-support.h"
/* Prototypes for local functions. */
char *p,
struct symtabs_and_lines *values);
-static struct symbol *locate_class_sym (char **argptr, char *p);
+static struct symbol *locate_compound_sym (char **argptr,
+ char *current_component,
+ const char *namespace);
+
+static int decode_namespace (char **argptr, int funfirstline,
+ char ***canonical,
+ char *next_component,
+ const char *namespace,
+ struct symtabs_and_lines *values);
static char *find_next_token (char **argptr);
const char *fmt, ...)
ATTR_NORETURN ATTR_FORMAT (printf, 2, 3);
-static struct symtab *handle_filename (char **argptr, char *filename_end,
- int is_quote_enclosed);
+static struct symtab *symtab_from_filename (char **argptr,
+ char *filename_end,
+ int is_quote_enclosed);
static int is_all_digits (char *arg);
/* No, the first part is a filename; set file_symtab
accordingly. Also, move argptr past the filename. */
- file_symtab = handle_filename (argptr, p, is_quote_enclosed);
+ file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed);
}
}
char *saved_arg, char *current_component,
struct symtabs_and_lines *values)
{
- char *copy;
- struct symbol *class_sym;
- struct type *t;
-
- /* If CURRENT_COMPONENT points at the end of a name of a class, find
- the corresponding symbol and advance ARGPTR past the end of the
- class. */
+ const char *namespace = "";
+
+ while (1)
+ {
+ char *copy;
+ struct symbol *class_sym;
+ struct type *t;
- class_sym = locate_class_sym (argptr, current_component);
+ /* If CURRENT_COMPONENT points at the end of a name of a class
+ or namespace, find the corresponding symbol and advance
+ ARGPTR past the end of the class/namespace. */
- if (class_sym == NULL)
- return 0;
+ class_sym = locate_compound_sym (argptr, current_component, namespace);
- t = check_typedef (SYMBOL_TYPE (class_sym));
+ if (class_sym == NULL)
+ return 0;
- switch (TYPE_CODE (t))
- {
- case TYPE_CODE_STRUCT:
- case TYPE_CODE_UNION:
- /* Find the next token (everything up to end or next blank). */
-
- current_component = find_next_token (argptr);
- copy = alloca (current_component - *argptr + 1);
- memcpy (copy, *argptr, current_component - *argptr);
- copy[current_component - *argptr] = '\0';
- if (current_component != *argptr
- && copy[current_component - *argptr - 1]
- && (strchr (get_gdb_completer_quote_characters (),
- copy[current_component - *argptr - 1])
- != NULL))
- copy[current_component - *argptr - 1] = '\0';
+ t = check_typedef (SYMBOL_TYPE (class_sym));
+
+ switch (TYPE_CODE (t))
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ /* Find the next token (everything up to end or next blank). */
+
+ current_component = find_next_token (argptr);
+ copy = alloca (current_component - *argptr + 1);
+ memcpy (copy, *argptr, current_component - *argptr);
+ copy[current_component - *argptr] = '\0';
+ if (current_component != *argptr
+ && copy[current_component - *argptr - 1]
+ && (strchr (get_gdb_completer_quote_characters (),
+ copy[current_component - *argptr - 1])
+ != NULL))
+ copy[current_component - *argptr - 1] = '\0';
- while (*current_component == ' ' || *current_component == '\t')
- current_component++;
- *argptr = current_component;
+ while (*current_component == ' ' || *current_component == '\t')
+ current_component++;
+ *argptr = current_component;
- *values = find_method (funfirstline, canonical, saved_arg, copy,
- t, class_sym);
+ *values = find_method (funfirstline, canonical, saved_arg, copy,
+ t, class_sym);
- return 1;
- case TYPE_CODE_NAMESPACE:
- return 0;
- default:
- /* FIXME: carlton/2002-11-19: Once this all settles down, this
- case should be an error rather than a return 0; that will
- allow us to make VALUES the return value rather than an
- argument. */
- return 0;
+ return 1;
+ case TYPE_CODE_NAMESPACE:
+ {
+ char *next_component = find_next_token (argptr);
+ namespace = TYPE_TAG_NAME (t);
+ if (*next_component == ':')
+ {
+ current_component = next_component;
+ break;
+ }
+ else
+ {
+ return decode_namespace (argptr, funfirstline,
+ canonical,
+ next_component, namespace,
+ values);
+ }
+ }
+ default:
+ /* FIXME: carlton/2002-11-19: Once this all settles down, this
+ case should be an error rather than a return 0; that will
+ allow us to make VALUES the return value rather than an
+ argument. */
+ return 0;
+ }
}
}
+/* Locate a symbol associated to a class/namespace that starts at
+ *argptr and ends at current_component, looking for it in the
+ namespace NAMESPACE. Advance *ARGPTR to the start of the next
+ component. It's the caller's responsibility to verify that the
+ symbol in question is non-NULL and of the correct type. */
+
static struct symbol *
-locate_class_sym (char **argptr, char *p)
+locate_compound_sym (char **argptr, char *current_component,
+ const char *namespace)
{
char *p1;
char *copy;
- /* Extract the class name. */
- p1 = p;
- while (p != *argptr && p[-1] == ' ')
- --p;
- copy = alloca (p - *argptr + 1);
- memcpy (copy, *argptr, p - *argptr);
- copy[p - *argptr] = 0;
+ /* Extract the class/namespace name. */
+ p1 = current_component;
+ while (current_component != *argptr && current_component[-1] == ' ')
+ --current_component;
+ copy = alloca (current_component - *argptr + 1);
+ memcpy (copy, *argptr, current_component - *argptr);
+ copy[current_component - *argptr] = 0;
/* Discard the class name from the arg. */
- p = p1 + (p1[0] == ':' ? 2 : 1);
- while (*p == ' ' || *p == '\t')
- p++;
- *argptr = p;
+ current_component = p1 + (p1[0] == ':' ? 2 : 1);
+ while (*current_component == ' ' || *current_component == '\t')
+ current_component++;
+ *argptr = current_component;
+
+ return lookup_symbol_namespace (namespace, strlen (namespace),
+ copy, NULL, get_selected_block(0),
+ VAR_NAMESPACE, NULL);
+}
+
+/* Try to look up the symbol in the namespace NAMESPACE whose name
+ starts at *ARGPTR and ends at *NEXT_COMPONENT. If successful,
+ return 1 and store an appropriate symtabs_and_lines in VALUES;
+ otherwise, return 0. */
+
+/* FIXME: carlton/2003-02-12: The only reason for not just returning
+ the symtabs_and_lines directly (and signalling an error if an
+ appropriate one can't be produced) is because
+ examine_compound_token wants it for historical reasons; I sure
+ don't like it. */
+
+static int
+decode_namespace (char **argptr, int funfirstline,
+ char ***canonical,
+ char *next_component, const char *namespace,
+ struct symtabs_and_lines *values)
+{
+ char *copy;
+ struct symbol *sym;
+ struct symtab *sym_symtab;
+
+ copy = alloca (next_component - *argptr + 1);
+ memcpy (copy, *argptr, next_component - *argptr);
+ copy[next_component - *argptr] = '\0';
+ *argptr = next_component;
- return lookup_symbol (copy, NULL, STRUCT_NAMESPACE, NULL, NULL);
+ sym = lookup_symbol_namespace (namespace, strlen (namespace),
+ copy, NULL, get_selected_block(0),
+ VAR_NAMESPACE, &sym_symtab);
+
+ if (sym != NULL)
+ {
+ *values = symbol_found (funfirstline, canonical, copy,
+ sym, NULL, sym_symtab);
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
}
/* Find the next token (presumably a method name); if some of it is
of *ARGPTR ending at FILE_NAME_END. */
static struct symtab *
-handle_filename (char **argptr, char *filename_end, int is_quote_enclosed)
+symtab_from_filename (char **argptr, char *filename_end,
+ int is_quote_enclosed)
{
char *saved_filename_end;
char *copy;