domain_enum);
static struct symbol *lookup_symbol_aux (const char *name,
- const char *mangled_name,
+ const char *linkage_name,
const struct block *block,
const domain_enum domain,
int *is_a_field_of_this,
static
struct symbol *lookup_symbol_aux_local (const char *name,
- const char *mangled_name,
- const struct block *block,
- const domain_enum domain,
- struct symtab **symtab,
- const struct block **static_block);
-
-static
-struct symbol *lookup_symbol_aux_block (const char *name,
- const char *mangled_name,
+ const char *linkage_name,
const struct block *block,
const domain_enum domain,
struct symtab **symtab);
static
struct symbol *lookup_symbol_aux_symtabs (int block_index,
const char *name,
- const char *mangled_name,
+ const char *linkage_name,
const domain_enum domain,
struct symtab **symtab);
static
struct symbol *lookup_symbol_aux_psymtabs (int block_index,
const char *name,
- const char *mangled_name,
+ const char *linkage_name,
const domain_enum domain,
struct symtab **symtab);
#if 0
static
struct symbol *lookup_symbol_aux_minsyms (const char *name,
- const char *mangled_name,
+ const char *linkage_name,
const domain_enum domain,
int *is_a_field_of_this,
struct symtab **symtab);
return returnval;
}
+/* Behave like lookup_symbol_aux except that NAME is the natural name
+ of the symbol that we're looking for and, if LINKAGE_NAME is
+ non-NULL, ensure that the symbol's linkage name matches as
+ well. */
+
static struct symbol *
-lookup_symbol_aux (const char *name, const char *mangled_name,
+lookup_symbol_aux (const char *name, const char *linkage_name,
const struct block *block, const domain_enum domain,
int *is_a_field_of_this, struct symtab **symtab)
{
struct symbol *sym;
- const struct block *static_block;
/* Search specified block and its superiors. Don't search
STATIC_BLOCK or GLOBAL_BLOCK. */
- sym = lookup_symbol_aux_local (name, mangled_name, block, domain,
- symtab, &static_block);
+ sym = lookup_symbol_aux_local (name, linkage_name, block, domain,
+ symtab);
if (sym != NULL)
return sym;
-#if 0
- /* NOTE: carlton/2002-11-05: At the time that this code was
- #ifdeffed out, the value of 'block' was always NULL at this
- point, hence the bemused comments below. */
-
- /* FIXME: this code is never executed--block is always NULL at this
- point. What is it trying to do, anyway? We already should have
- checked the STATIC_BLOCK above (it is the superblock of top-level
- blocks). Why is VAR_DOMAIN special-cased? */
- /* Don't need to mess with the psymtabs; if we have a block,
- that file is read in. If we don't, then we deal later with
- all the psymtab stuff that needs checking. */
- /* Note (RT): The following never-executed code looks unnecessary to me also.
- * If we change the code to use the original (passed-in)
- * value of 'block', we could cause it to execute, but then what
- * would it do? The STATIC_BLOCK of the symtab containing the passed-in
- * 'block' was already searched by the above code. And the STATIC_BLOCK's
- * of *other* symtabs (those files not containing 'block' lexically)
- * should not contain 'block' address-wise. So we wouldn't expect this
- * code to find any 'sym''s that were not found above. I vote for
- * deleting the following paragraph of code.
- */
- if (domain == VAR_DOMAIN && block != NULL)
- {
- struct block *b;
- /* Find the right symtab. */
- ALL_SYMTABS (objfile, s)
- {
- bv = BLOCKVECTOR (s);
- b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- if (BLOCK_START (b) <= BLOCK_START (block)
- && BLOCK_END (b) > BLOCK_START (block))
- {
- sym = lookup_block_symbol (b, name, mangled_name, VAR_DOMAIN);
- if (sym)
- {
- block_found = b;
- if (symtab != NULL)
- *symtab = s;
- return fixup_symbol_section (sym, objfile);
- }
- }
- }
- }
-#endif /* 0 */
+ /* If requested to do so by the caller and if appropriate for the
+ current language, check to see if NAME is a field of `this'. */
- /* C++/Java/Objective-C: If requested to do so by the caller,
- check to see if NAME is a field of `this'. */
- if (is_a_field_of_this)
+ if (current_language->la_value_of_this != NULL
+ && is_a_field_of_this != NULL)
{
- struct value *v = value_of_this (0);
+ struct value *v = current_language->la_value_of_this (0);
*is_a_field_of_this = 0;
if (v && check_field (v, name))
}
}
- /* If there's a static block to search, search it next. */
-
- /* NOTE: carlton/2002-12-05: There is a question as to whether or
- not it would be appropriate to search the current global block
- here as well. (That's what this code used to do before the
- is_a_field_of_this check was moved up.) On the one hand, it's
- redundant with the lookup_symbol_aux_symtabs search that happens
- next. On the other hand, if decode_line_1 is passed an argument
- like filename:var, then the user presumably wants 'var' to be
- searched for in filename. On the third hand, there shouldn't be
- multiple global variables all of which are named 'var', and it's
- not like decode_line_1 has ever restricted its search to only
- global variables in a single filename. All in all, only
- searching the static block here seems best: it's correct and it's
- cleanest. */
-
- /* NOTE: carlton/2002-12-05: There's also a possible performance
- issue here: if you usually search for global symbols in the
- current file, then it would be slightly better to search the
- current global block before searching all the symtabs. But there
- are other factors that have a much greater effect on performance
- than that one, so I don't think we should worry about that for
- now. */
-
- if (static_block != NULL)
- {
- sym = lookup_symbol_aux_block (name, mangled_name, static_block,
- domain, symtab);
- if (sym != NULL)
- return sym;
- }
-
- /* Now search all global blocks. Do the symtab's first, then
- check the psymtab's. If a psymtab indicates the existence
- of the desired name as a global, then do psymtab-to-symtab
- conversion on the fly and return the found symbol. */
+ /* Now do whatever is appropriate for the current language to look
+ up static and global variables. */
- sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, mangled_name,
- domain, symtab);
- if (sym != NULL)
- return sym;
-
- sym = lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, mangled_name,
- domain, symtab);
+ sym = current_language->la_lookup_symbol_nonlocal (name, linkage_name,
+ block, domain,
+ symtab);
if (sym != NULL)
return sym;
desired name as a file-level static, then do psymtab-to-symtab
conversion on the fly and return the found symbol. */
- sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, mangled_name,
+ sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, linkage_name,
domain, symtab);
if (sym != NULL)
return sym;
- sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, mangled_name,
+ sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, linkage_name,
domain, symtab);
if (sym != NULL)
return sym;
}
/* Check to see if the symbol is defined in BLOCK or its superiors.
- Don't search STATIC_BLOCK or GLOBAL_BLOCK. If we don't find a
- match, store the address of STATIC_BLOCK in static_block. */
+ Don't search STATIC_BLOCK or GLOBAL_BLOCK. */
static struct symbol *
-lookup_symbol_aux_local (const char *name, const char *mangled_name,
+lookup_symbol_aux_local (const char *name, const char *linkage_name,
const struct block *block,
const domain_enum domain,
- struct symtab **symtab,
- const struct block **static_block)
+ struct symtab **symtab)
{
struct symbol *sym;
-
+ const struct block *static_block = block_static_block (block);
+
/* Check if either no block is specified or it's a global block. */
- if (block == NULL || BLOCK_SUPERBLOCK (block) == NULL)
- {
- *static_block = NULL;
- return NULL;
- }
+ if (static_block == NULL)
+ return NULL;
- while (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) != NULL)
+ while (block != static_block)
{
- sym = lookup_symbol_aux_block (name, mangled_name, block, domain,
+ sym = lookup_symbol_aux_block (name, linkage_name, block, domain,
symtab);
if (sym != NULL)
return sym;
block = BLOCK_SUPERBLOCK (block);
}
- /* We've reached the static block. */
+ /* We've reached the static block without finding a result. */
- *static_block = block;
return NULL;
}
/* Look up a symbol in a block; if found, locate its symtab, fixup the
symbol, and set block_found appropriately. */
-static struct symbol *
-lookup_symbol_aux_block (const char *name, const char *mangled_name,
+struct symbol *
+lookup_symbol_aux_block (const char *name, const char *linkage_name,
const struct block *block,
const domain_enum domain,
struct symtab **symtab)
struct block *b;
struct symtab *s = NULL;
- sym = lookup_block_symbol (block, name, mangled_name, domain);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
if (sym)
{
block_found = block;
static struct symbol *
lookup_symbol_aux_symtabs (int block_index,
- const char *name, const char *mangled_name,
+ const char *name, const char *linkage_name,
const domain_enum domain,
struct symtab **symtab)
{
{
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, block_index);
- sym = lookup_block_symbol (block, name, mangled_name, domain);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
if (sym)
{
block_found = block;
static struct symbol *
lookup_symbol_aux_psymtabs (int block_index, const char *name,
- const char *mangled_name,
+ const char *linkage_name,
const domain_enum domain,
struct symtab **symtab)
{
ALL_PSYMTABS (objfile, ps)
{
if (!ps->readin
- && lookup_partial_symbol (ps, name, mangled_name,
+ && lookup_partial_symbol (ps, name, linkage_name,
psymtab_index, domain))
{
s = PSYMTAB_TO_SYMTAB (ps);
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, block_index);
- sym = lookup_block_symbol (block, name, mangled_name, domain);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
if (!sym)
{
/* This shouldn't be necessary, but as a last resort try
block = BLOCKVECTOR_BLOCK (bv,
block_index == GLOBAL_BLOCK ?
STATIC_BLOCK : GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, mangled_name, domain);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
if (!sym)
error ("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s<type>).",
block_index == GLOBAL_BLOCK ? "global" : "static",
static struct symbol *
lookup_symbol_aux_minsyms (const char *name,
- const char *mangled_name,
+ const char *linkage_name,
const domain_enum domain,
int *is_a_field_of_this,
struct symtab **symtab)
to be clearly the wrong thing to pass as the
unmangled name. */
sym =
- lookup_block_symbol (block, name, mangled_name, domain);
+ lookup_block_symbol (block, name, linkage_name, domain);
/* We kept static functions in minimal symbol table as well as
in static scope. We want to find them in the symbol table. */
if (!sym)
{
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
sym = lookup_block_symbol (block, name,
- mangled_name, domain);
+ linkage_name, domain);
}
/* NOTE: carlton/2002-12-04: The following comment was
}
#endif /* 0 */
+/* A default version of lookup_symbol_nonlocal for use by languages
+ that can't think of anything better to do. This implements the C
+ lookup rules. */
+
+struct symbol *
+basic_lookup_symbol_nonlocal (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain,
+ struct symtab **symtab)
+{
+ struct symbol *sym;
+
+ /* NOTE: carlton/2003-05-19: The comments below were written when
+ this (or what turned into this) was part of lookup_symbol_aux;
+ I'm much less worried about these questions now, since these
+ decisions have turned out well, but I leave these comments here
+ for posterity. */
+
+ /* NOTE: carlton/2002-12-05: There is a question as to whether or
+ not it would be appropriate to search the current global block
+ here as well. (That's what this code used to do before the
+ is_a_field_of_this check was moved up.) On the one hand, it's
+ redundant with the lookup_symbol_aux_symtabs search that happens
+ next. On the other hand, if decode_line_1 is passed an argument
+ like filename:var, then the user presumably wants 'var' to be
+ searched for in filename. On the third hand, there shouldn't be
+ multiple global variables all of which are named 'var', and it's
+ not like decode_line_1 has ever restricted its search to only
+ global variables in a single filename. All in all, only
+ searching the static block here seems best: it's correct and it's
+ cleanest. */
+
+ /* NOTE: carlton/2002-12-05: There's also a possible performance
+ issue here: if you usually search for global symbols in the
+ current file, then it would be slightly better to search the
+ current global block before searching all the symtabs. But there
+ are other factors that have a much greater effect on performance
+ than that one, so I don't think we should worry about that for
+ now. */
+
+ sym = lookup_symbol_static (name, linkage_name, block, domain, symtab);
+ if (sym != NULL)
+ return sym;
+
+ return lookup_symbol_global (name, linkage_name, domain, symtab);
+}
+
+/* Lookup a symbol in the static block associated to BLOCK, if there
+ is one; do nothing if BLOCK is NULL or a global block. */
+
+struct symbol *
+lookup_symbol_static (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain,
+ struct symtab **symtab)
+{
+ const struct block *static_block = block_static_block (block);
+
+ if (static_block != NULL)
+ return lookup_symbol_aux_block (name, linkage_name, static_block,
+ domain, symtab);
+ else
+ return NULL;
+}
+
+/* Lookup a symbol in all files' global blocks (searching psymtabs if
+ necessary). */
+
+struct symbol *
+lookup_symbol_global (const char *name,
+ const char *linkage_name,
+ const domain_enum domain,
+ struct symtab **symtab)
+{
+ struct symbol *sym;
+
+ sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
+ domain, symtab);
+ if (sym != NULL)
+ return sym;
+
+ return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name,
+ domain, symtab);
+}
+
/* Look, in partial_symtab PST, for symbol whose natural name is NAME.
If LINKAGE_NAME is non-NULL, check in addition that the symbol's
linkage name matches it. Check the global symbols if GLOBAL, the
symbol (language_cplus or language_objc set) has both the encoded and
non-encoded names tested for a match.
- If MANGLED_NAME is non-NULL, verify that any symbol we find has this
+ If LINKAGE_NAME is non-NULL, verify that any symbol we find has this
particular mangled name.
*/
struct symbol *
lookup_block_symbol (register const struct block *block, const char *name,
- const char *mangled_name,
+ const char *linkage_name,
const domain_enum domain)
{
register int bot, top, inc;
for (sym = BLOCK_BUCKET (block, hash_index); sym; sym = sym->hash_next)
{
if (SYMBOL_DOMAIN (sym) == domain
- && (mangled_name
- ? strcmp (DEPRECATED_SYMBOL_NAME (sym), mangled_name) == 0
+ && (linkage_name
+ ? strcmp (DEPRECATED_SYMBOL_NAME (sym), linkage_name) == 0
: SYMBOL_MATCHES_NATURAL_NAME (sym, name)))
return sym;
}
{
sym = BLOCK_SYM (block, bot);
if (SYMBOL_DOMAIN (sym) == domain
- && (mangled_name
- ? strcmp (DEPRECATED_SYMBOL_NAME (sym), mangled_name) == 0
+ && (linkage_name
+ ? strcmp (DEPRECATED_SYMBOL_NAME (sym), linkage_name) == 0
: SYMBOL_MATCHES_NATURAL_NAME (sym, name)))
{
return sym;
{
sym = BLOCK_SYM (block, bot);
if (SYMBOL_DOMAIN (sym) == domain
- && (mangled_name
- ? strcmp (DEPRECATED_SYMBOL_NAME (sym), mangled_name) == 0
+ && (linkage_name
+ ? strcmp (DEPRECATED_SYMBOL_NAME (sym), linkage_name) == 0
: SYMBOL_MATCHES_NATURAL_NAME (sym, name)))
{
/* If SYM has aliases, then use any alias that is active
}
}
+/* ObjC: In case we are completing on a selector, look as the msymbol
+ again and feed all the selectors into the mill. */
+
+static void
+completion_list_objc_symbol (struct minimal_symbol *msymbol, char *sym_text,
+ int sym_text_len, char *text, char *word)
+{
+ static char *tmp = NULL;
+ static unsigned int tmplen = 0;
+
+ char *method, *category, *selector;
+ char *tmp2 = NULL;
+
+ method = SYMBOL_NATURAL_NAME (msymbol);
+
+ /* Is it a method? */
+ if ((method[0] != '-') && (method[0] != '+'))
+ return;
+
+ if (sym_text[0] == '[')
+ /* Complete on shortened method method. */
+ completion_list_add_name (method + 1, sym_text, sym_text_len, text, word);
+
+ while ((strlen (method) + 1) >= tmplen)
+ {
+ if (tmplen == 0)
+ tmplen = 1024;
+ else
+ tmplen *= 2;
+ tmp = xrealloc (tmp, tmplen);
+ }
+ selector = strchr (method, ' ');
+ if (selector != NULL)
+ selector++;
+
+ category = strchr (method, '(');
+
+ if ((category != NULL) && (selector != NULL))
+ {
+ memcpy (tmp, method, (category - method));
+ tmp[category - method] = ' ';
+ memcpy (tmp + (category - method) + 1, selector, strlen (selector) + 1);
+ completion_list_add_name (tmp, sym_text, sym_text_len, text, word);
+ if (sym_text[0] == '[')
+ completion_list_add_name (tmp + 1, sym_text, sym_text_len, text, word);
+ }
+
+ if (selector != NULL)
+ {
+ /* Complete on selector only. */
+ strcpy (tmp, selector);
+ tmp2 = strchr (tmp, ']');
+ if (tmp2 != NULL)
+ *tmp2 = '\0';
+
+ completion_list_add_name (tmp, sym_text, sym_text_len, text, word);
+ }
+}
+
+/* Break the non-quoted text based on the characters which are in
+ symbols. FIXME: This should probably be language-specific. */
+
+static char *
+language_search_unquoted_string (char *text, char *p)
+{
+ for (; p > text; --p)
+ {
+ if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
+ continue;
+ else
+ {
+ if ((current_language->la_language == language_objc))
+ {
+ if (p[-1] == ':') /* might be part of a method name */
+ continue;
+ else if (p[-1] == '[' && (p[-2] == '-' || p[-2] == '+'))
+ p -= 2; /* beginning of a method name */
+ else if (p[-1] == ' ' || p[-1] == '(' || p[-1] == ')')
+ { /* might be part of a method name */
+ char *t = p;
+
+ /* Seeing a ' ' or a '(' is not conclusive evidence
+ that we are in the middle of a method name. However,
+ finding "-[" or "+[" should be pretty un-ambiguous.
+ Unfortunately we have to find it now to decide. */
+
+ while (t > text)
+ if (isalnum (t[-1]) || t[-1] == '_' ||
+ t[-1] == ' ' || t[-1] == ':' ||
+ t[-1] == '(' || t[-1] == ')')
+ --t;
+ else
+ break;
+
+ if (t[-1] == '[' && (t[-2] == '-' || t[-2] == '+'))
+ p = t - 2; /* method name detected */
+ /* else we leave with p unchanged */
+ }
+ }
+ break;
+ }
+ }
+ return p;
+}
+
+
/* Return a NULL terminated array of all symbols (regardless of class)
which begin by matching TEXT. If the answer is no symbols, then
the return value is an array which contains only a NULL pointer.
{
QUIT;
COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, word);
+
+ completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text, word);
}
/* Search upwards from currently selected frame (so that we can
ALL_BLOCK_SYMBOLS (b, i, sym)
{
+ QUIT;
COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
{
}
else
{
- /* It is not a quoted string. Break it based on the characters
- which are in symbols. */
- while (p > text)
- {
- if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
- --p;
- else
- break;
- }
- sym_text = p;
+ /* Not a quoted string. */
+ sym_text = language_search_unquoted_string (text, p);
}
}