along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Sections of code marked
+
+ #ifdef GNAT_GDB
+ ...
+ #endif
+
+ indicate sections that are used in sources distributed by
+ ACT, Inc., but not yet integrated into the public tree (where
+ GNAT_GDB is not defined). They are retained here nevertheless
+ to minimize the problems of maintaining different versions
+ of the source and to make the full source available. */
+
#include "defs.h"
#include <stdio.h>
#include "gdb_string.h"
#define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2)
#endif
+#ifdef GNAT_GDB
/* A structure that contains a vector of strings.
The main purpose of this type is to group the vector and its
associated parameters in one structure. This makes it easier
static struct string_vector xnew_string_vector (int initial_size);
static void string_vector_append (struct string_vector *sv, char *str);
+#endif /* GNAT_GDB */
static const char *ada_unqualified_name (const char *decoded_name);
static char *add_angle_brackets (const char *str);
/* Utilities */
+#ifdef GNAT_GDB
+
/* Create a new empty string_vector struct with an initial size of
INITIAL_SIZE. */
return result;
}
+#endif /* GNAT_GDB */
+
static char *
ada_get_gdb_completer_word_break_characters (void)
{
return lang;
}
+
+/* If the main procedure is written in Ada, then return its name.
+ The result is good until the next call. Return NULL if the main
+ procedure doesn't appear to be in Ada. */
+
+char *
+ada_main_name (void)
+{
+ struct minimal_symbol *msym;
+ CORE_ADDR main_program_name_addr;
+ static char main_program_name[1024];
+ /* For Ada, the name of the main procedure is stored in a specific
+ string constant, generated by the binder. Look for that symbol,
+ extract its address, and then read that string. If we didn't find
+ that string, then most probably the main procedure is not written
+ in Ada. */
+ msym = lookup_minimal_symbol (ADA_MAIN_PROGRAM_SYMBOL_NAME, NULL, NULL);
+
+ if (msym != NULL)
+ {
+ main_program_name_addr = SYMBOL_VALUE_ADDRESS (msym);
+ if (main_program_name_addr == 0)
+ error ("Invalid address for Ada main program name.");
+
+ extract_string (main_program_name_addr, main_program_name);
+ return main_program_name;
+ }
+
+ /* The main procedure doesn't seem to be in Ada. */
+ return NULL;
+}
\f
/* Symbols */
\f
/* Experimental Symbol Cache Module */
+/* This module may well have been OBE, due to improvements in the
+ symbol-table module. So until proven otherwise, it is disabled in
+ the submitted public code, and may be removed from all sources
+ in the future. */
+
+#ifdef GNAT_GDB
+
/* This section implements a simple, fixed-sized hash table for those
Ada-mode symbols that get looked up in the course of executing the user's
commands. The size is fixed on the grounds that there are not
e->symtab = symtab;
e->block = block;
}
+
+#else
+static int
+lookup_cached_symbol (const char *name, domain_enum namespace,
+ struct symbol **sym, struct block **block,
+ struct symtab **symtab)
+{
+ return 0;
+}
+
+static void
+cache_symbol (const char *name, domain_enum namespace, struct symbol *sym,
+ struct block *block, struct symtab *symtab)
+{
+}
+#endif /* GNAT_GDB */
\f
/* Symbol Lookup */
return (struct ada_symbol_info *) obstack_base (obstackp);
}
-/* If SYM_NAME is a completion candidate for TEXT, return this symbol
- name in a form that's appropriate for the completion. The result
- does not need to be deallocated, but is only good until the next call.
-
- TEXT_LEN is equal to the length of TEXT.
- Perform a wild match if WILD_MATCH is set.
- ENCODED should be set if TEXT represents the start of a symbol name
- in its encoded form. */
+/* Look, in partial_symtab PST, for symbol NAME in given namespace.
+ Check the global symbols if GLOBAL, the static symbols if not.
+ Do wild-card match if WILD. */
-static const char *
-symbol_completion_match (const char *sym_name,
- const char *text, int text_len,
- int wild_match, int encoded)
+static struct partial_symbol *
+ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name,
+ int global, domain_enum namespace, int wild)
{
- char *result;
- const int verbatim_match = (text[0] == '<');
- int match = 0;
+ struct partial_symbol **start;
+ int name_len = strlen (name);
+ int length = (global ? pst->n_global_syms : pst->n_static_syms);
+ int i;
- if (verbatim_match)
+ if (length == 0)
{
- /* Strip the leading angle bracket. */
- text = text + 1;
- text_len--;
+ return (NULL);
}
- /* First, test against the fully qualified name of the symbol. */
-
- if (strncmp (sym_name, text, text_len) == 0)
- match = 1;
-
- if (match && !encoded)
- {
- /* One needed check before declaring a positive match is to verify
- that iff we are doing a verbatim match, the decoded version
- of the symbol name starts with '<'. Otherwise, this symbol name
- is not a suitable completion. */
- const char *sym_name_copy = sym_name;
- int has_angle_bracket;
-
- sym_name = ada_decode (sym_name);
- has_angle_bracket = (sym_name [0] == '<');
- match = (has_angle_bracket == verbatim_match);
- sym_name = sym_name_copy;
- }
+ start = (global ?
+ pst->objfile->global_psymbols.list + pst->globals_offset :
+ pst->objfile->static_psymbols.list + pst->statics_offset);
- if (match && !verbatim_match)
+ if (wild)
{
- /* When doing non-verbatim match, another check that needs to
- be done is to verify that the potentially matching symbol name
- does not include capital letters, because the ada-mode would
- not be able to understand these symbol names without the
- angle bracket notation. */
- const char *tmp;
+ for (i = 0; i < length; i += 1)
+ {
+ struct partial_symbol *psym = start[i];
- for (tmp = sym_name; *tmp != '\0' && !isupper (*tmp); tmp++);
- if (*tmp != '\0')
- match = 0;
+ if (SYMBOL_DOMAIN (psym) == namespace &&
+ wild_match (name, name_len, SYMBOL_LINKAGE_NAME (psym)))
+ return psym;
+ }
+ return NULL;
}
+ else
+ {
+ if (global)
+ {
+ int U;
+ i = 0;
+ U = length - 1;
+ while (U - i > 4)
+ {
+ int M = (U + i) >> 1;
+ struct partial_symbol *psym = start[M];
+ if (SYMBOL_LINKAGE_NAME (psym)[0] < name[0])
+ i = M + 1;
+ else if (SYMBOL_LINKAGE_NAME (psym)[0] > name[0])
+ U = M - 1;
+ else if (strcmp (SYMBOL_LINKAGE_NAME (psym), name) < 0)
+ i = M + 1;
+ else
+ U = M;
+ }
+ }
+ else
+ i = 0;
- /* Second: Try wild matching... */
+ while (i < length)
+ {
+ struct partial_symbol *psym = start[i];
- if (!match && wild_match)
- {
- /* Since we are doing wild matching, this means that TEXT
- may represent an unqualified symbol name. We therefore must
- also compare TEXT against the unqualified name of the symbol. */
- sym_name = ada_unqualified_name (ada_decode (sym_name));
+ if (SYMBOL_DOMAIN (psym) == namespace)
+ {
+ int cmp = strncmp (name, SYMBOL_LINKAGE_NAME (psym), name_len);
- if (strncmp (sym_name, text, text_len) == 0)
- match = 1;
- }
+ if (cmp < 0)
+ {
+ if (global)
+ break;
+ }
+ else if (cmp == 0
+ && is_name_suffix (SYMBOL_LINKAGE_NAME (psym)
+ + name_len))
+ return psym;
+ }
+ i += 1;
+ }
- /* Finally: If we found a mach, prepare the result to return. */
+ if (global)
+ {
+ int U;
+ i = 0;
+ U = length - 1;
+ while (U - i > 4)
+ {
+ int M = (U + i) >> 1;
+ struct partial_symbol *psym = start[M];
+ if (SYMBOL_LINKAGE_NAME (psym)[0] < '_')
+ i = M + 1;
+ else if (SYMBOL_LINKAGE_NAME (psym)[0] > '_')
+ U = M - 1;
+ else if (strcmp (SYMBOL_LINKAGE_NAME (psym), "_ada_") < 0)
+ i = M + 1;
+ else
+ U = M;
+ }
+ }
+ else
+ i = 0;
- if (!match)
- return NULL;
+ while (i < length)
+ {
+ struct partial_symbol *psym = start[i];
- if (verbatim_match)
- sym_name = add_angle_brackets (sym_name);
+ if (SYMBOL_DOMAIN (psym) == namespace)
+ {
+ int cmp;
- if (!encoded)
- sym_name = ada_decode (sym_name);
+ cmp = (int) '_' - (int) SYMBOL_LINKAGE_NAME (psym)[0];
+ if (cmp == 0)
+ {
+ cmp = strncmp ("_ada_", SYMBOL_LINKAGE_NAME (psym), 5);
+ if (cmp == 0)
+ cmp = strncmp (name, SYMBOL_LINKAGE_NAME (psym) + 5,
+ name_len);
+ }
- return sym_name;
+ if (cmp < 0)
+ {
+ if (global)
+ break;
+ }
+ else if (cmp == 0
+ && is_name_suffix (SYMBOL_LINKAGE_NAME (psym)
+ + name_len + 5))
+ return psym;
+ }
+ i += 1;
+ }
+ }
+ return NULL;
}
-/* A companion function to ada_make_symbol_completion_list().
- Check if SYM_NAME represents a symbol which name would be suitable
- to complete TEXT (TEXT_LEN is the length of TEXT), in which case
- it is appended at the end of the given string vector SV.
+/* Find a symbol table containing symbol SYM or NULL if none. */
- ORIG_TEXT is the string original string from the user command
- that needs to be completed. WORD is the entire command on which
- completion should be performed. These two parameters are used to
- determine which part of the symbol name should be added to the
- completion vector.
- if WILD_MATCH is set, then wild matching is performed.
- ENCODED should be set if TEXT represents a symbol name in its
- encoded formed (in which case the completion should also be
- encoded). */
-
-static void
-symbol_completion_add (struct string_vector *sv,
- const char *sym_name,
- const char *text, int text_len,
- const char *orig_text, const char *word,
- int wild_match, int encoded)
+static struct symtab *
+symtab_for_sym (struct symbol *sym)
{
- const char *match = symbol_completion_match (sym_name, text, text_len,
- wild_match, encoded);
- char *completion;
-
- if (match == NULL)
- return;
-
- /* We found a match, so add the appropriate completion to the given
- string vector. */
-
- if (word == orig_text)
- {
- completion = xmalloc (strlen (match) + 5);
- strcpy (completion, match);
- }
- else if (word > orig_text)
- {
- /* Return some portion of sym_name. */
- completion = xmalloc (strlen (match) + 5);
- strcpy (completion, match + (word - orig_text));
- }
- else
- {
- /* Return some of ORIG_TEXT plus sym_name. */
- completion = xmalloc (strlen (match) + (orig_text - word) + 5);
- strncpy (completion, word, orig_text - word);
- completion[orig_text - word] = '\0';
- strcat (completion, match);
- }
+ struct symtab *s;
+ struct objfile *objfile;
+ struct block *b;
+ struct symbol *tmp_sym;
+ struct dict_iterator iter;
+ int j;
- string_vector_append (sv, completion);
+ ALL_SYMTABS (objfile, s)
+ {
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_CONST:
+ case LOC_STATIC:
+ case LOC_TYPEDEF:
+ case LOC_REGISTER:
+ case LOC_LABEL:
+ case LOC_BLOCK:
+ case LOC_CONST_BYTES:
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+ ALL_BLOCK_SYMBOLS (b, iter, tmp_sym) if (sym == tmp_sym)
+ return s;
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+ ALL_BLOCK_SYMBOLS (b, iter, tmp_sym) if (sym == tmp_sym)
+ return s;
+ break;
+ default:
+ break;
+ }
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_REGISTER:
+ case LOC_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_LOCAL:
+ case LOC_TYPEDEF:
+ case LOC_LOCAL_ARG:
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
+ case LOC_COMPUTED:
+ case LOC_COMPUTED_ARG:
+ for (j = FIRST_LOCAL_BLOCK;
+ j < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (s)); j += 1)
+ {
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), j);
+ ALL_BLOCK_SYMBOLS (b, iter, tmp_sym) if (sym == tmp_sym)
+ return s;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return NULL;
}
-/* Return a list of possible symbol names completing TEXT0. The list
- is NULL terminated. WORD is the entire command on which completion
- is made. */
+/* Return a minimal symbol matching NAME according to Ada decoding
+ rules. Returns NULL if there is no such minimal symbol. Names
+ prefixed with "standard__" are handled specially: "standard__" is
+ first stripped off, and only static and global symbols are searched. */
-char **
-ada_make_symbol_completion_list (const char *text0, const char *word)
+struct minimal_symbol *
+ada_lookup_simple_minsym (const char *name)
{
- /* Note: This function is almost a copy of make_symbol_completion_list(),
- except it has been adapted for Ada. It is somewhat of a shame to
- duplicate so much code, but we don't really have the infrastructure
- yet to develop a language-aware version of he symbol completer... */
- char *text;
- int text_len;
- int wild_match;
- int encoded;
- struct string_vector result = xnew_string_vector (128);
- struct symbol *sym;
- struct symtab *s;
- struct partial_symtab *ps;
- struct minimal_symbol *msymbol;
struct objfile *objfile;
- struct block *b, *surrounding_static_block = 0;
- int i;
- struct dict_iterator iter;
+ struct minimal_symbol *msymbol;
+ int wild_match;
- if (text0[0] == '<')
+ if (strncmp (name, "standard__", sizeof ("standard__") - 1) == 0)
{
- text = xstrdup (text0);
- make_cleanup (xfree, text);
- text_len = strlen (text);
+ name += sizeof ("standard__") - 1;
wild_match = 0;
- encoded = 1;
}
else
- {
- text = xstrdup (ada_encode (text0));
- make_cleanup (xfree, text);
- text_len = strlen (text);
- for (i = 0; i < text_len; i++)
- text[i] = tolower (text[i]);
+ wild_match = (strstr (name, "__") == NULL);
- /* FIXME: brobecker/2003-09-17: When we get rid of ADA_RETAIN_DOTS,
- we can restrict the wild_match check to searching "__" only. */
- wild_match = (strstr (text0, "__") == NULL
- && strchr (text0, '.') == NULL);
- encoded = (strstr (text0, "__") != NULL);
- }
+ ALL_MSYMBOLS (objfile, msymbol)
+ {
+ if (ada_match_name (SYMBOL_LINKAGE_NAME (msymbol), name, wild_match)
+ && MSYMBOL_TYPE (msymbol) != mst_solib_trampoline)
+ return msymbol;
+ }
- /* First, look at the partial symtab symbols. */
- ALL_PSYMTABS (objfile, ps)
- {
- struct partial_symbol **psym;
+ return NULL;
+}
- /* If the psymtab's been read in we'll get it when we search
- through the blockvector. */
- if (ps->readin)
- continue;
+/* Return up minimal symbol for NAME, folded and encoded according to
+ Ada conventions, or NULL if none. The last two arguments are ignored. */
- for (psym = objfile->global_psymbols.list + ps->globals_offset;
- psym < (objfile->global_psymbols.list + ps->globals_offset
- + ps->n_global_syms);
- psym++)
- {
- QUIT;
- symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (*psym),
- text, text_len, text0, word,
- wild_match, encoded);
- }
+static struct minimal_symbol *
+ada_lookup_minimal_symbol (const char *name, const char *sfile,
+ struct objfile *objf)
+{
+ return ada_lookup_simple_minsym (ada_encode (name));
+}
- for (psym = objfile->static_psymbols.list + ps->statics_offset;
- psym < (objfile->static_psymbols.list + ps->statics_offset
- + ps->n_static_syms);
- psym++)
- {
- QUIT;
- symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (*psym),
- text, text_len, text0, word,
- wild_match, encoded);
- }
- }
+/* For all subprograms that statically enclose the subprogram of the
+ selected frame, add symbols matching identifier NAME in DOMAIN
+ and their blocks to the list of data in OBSTACKP, as for
+ ada_add_block_symbols (q.v.). If WILD, treat as NAME with a
+ wildcard prefix. */
- /* At this point scan through the misc symbol vectors and add each
- symbol you find to the list. Eventually we want to ignore
- anything that isn't a text symbol (everything else will be
- handled by the psymtab code above). */
+static void
+add_symbols_from_enclosing_procs (struct obstack *obstackp,
+ const char *name, domain_enum namespace,
+ int wild_match)
+{
+#ifdef HAVE_ADD_SYMBOLS_FROM_ENCLOSING_PROCS
+ /* Use a heuristic to find the frames of enclosing subprograms: treat the
+ pointer-sized value at location 0 from the local-variable base of a
+ frame as a static link, and then search up the call stack for a
+ frame with that same local-variable base. */
+ static struct symbol static_link_sym;
+ static struct symbol *static_link;
+ struct value *target_link_val;
- ALL_MSYMBOLS (objfile, msymbol)
- {
- QUIT;
- symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (msymbol),
- text, text_len, text0, word,
- wild_match, encoded);
- }
+ struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
+ struct frame_info *frame;
- /* Search upwards from currently selected frame (so that we can
- complete on local vars. */
+ if (! target_has_stack)
+ return;
- for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
+ if (static_link == NULL)
{
- if (!BLOCK_SUPERBLOCK (b))
- surrounding_static_block = b; /* For elmin of dups */
-
- ALL_BLOCK_SYMBOLS (b, iter, sym)
- {
- symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
- text, text_len, text0, word,
- wild_match, encoded);
- }
+ /* Initialize the local variable symbol that stands for the
+ static link (when there is one). */
+ static_link = &static_link_sym;
+ SYMBOL_LINKAGE_NAME (static_link) = "";
+ SYMBOL_LANGUAGE (static_link) = language_unknown;
+ SYMBOL_CLASS (static_link) = LOC_LOCAL;
+ SYMBOL_DOMAIN (static_link) = VAR_DOMAIN;
+ SYMBOL_TYPE (static_link) = lookup_pointer_type (builtin_type_void);
+ SYMBOL_VALUE (static_link) =
+ -(long) TYPE_LENGTH (SYMBOL_TYPE (static_link));
}
- /* Go through the symtabs and check the externs and statics for
- symbols which match. */
-
- ALL_SYMTABS (objfile, s)
- {
- QUIT;
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
- ALL_BLOCK_SYMBOLS (b, iter, sym)
- {
- symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
- text, text_len, text0, word,
- wild_match, encoded);
- }
- }
+ frame = get_selected_frame ();
+ if (frame == NULL
+ || inside_main_func (get_frame_address_in_block (frame)))
+ return;
- ALL_SYMTABS (objfile, s)
- {
- QUIT;
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
- /* Don't do this block twice. */
- if (b == surrounding_static_block)
- continue;
- ALL_BLOCK_SYMBOLS (b, iter, sym)
- {
- symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
- text, text_len, text0, word,
- wild_match, encoded);
- }
- }
-
- /* Append the closing NULL entry. */
- string_vector_append (&result, NULL);
+ target_link_val = read_var_value (static_link, frame);
+ while (target_link_val != NULL
+ && num_defns_collected (obstackp) == 0
+ && frame_relative_level (frame) <= MAX_ENCLOSING_FRAME_LEVELS)
+ {
+ CORE_ADDR target_link = value_as_address (target_link_val);
- return (result.array);
-}
+ frame = get_prev_frame (frame);
+ if (frame == NULL)
+ break;
-/* Look, in partial_symtab PST, for symbol NAME in given namespace.
- Check the global symbols if GLOBAL, the static symbols if not.
- Do wild-card match if WILD. */
+ if (get_frame_locals_address (frame) == target_link)
+ {
+ struct block *block;
+
+ QUIT;
-static struct partial_symbol *
-ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name,
- int global, domain_enum namespace, int wild)
-{
- struct partial_symbol **start;
- int name_len = strlen (name);
- int length = (global ? pst->n_global_syms : pst->n_static_syms);
- int i;
+ block = get_frame_block (frame, 0);
+ while (block != NULL && block_function (block) != NULL
+ && num_defns_collected (obstackp) == 0)
+ {
+ QUIT;
- if (length == 0)
- {
- return (NULL);
+ ada_add_block_symbols (obstackp, block, name, namespace,
+ NULL, NULL, wild_match);
+
+ block = BLOCK_SUPERBLOCK (block);
+ }
+ }
}
- start = (global ?
- pst->objfile->global_psymbols.list + pst->globals_offset :
- pst->objfile->static_psymbols.list + pst->statics_offset);
-
- if (wild)
- {
- for (i = 0; i < length; i += 1)
- {
- struct partial_symbol *psym = start[i];
+ do_cleanups (old_chain);
+#endif
+}
- if (SYMBOL_DOMAIN (psym) == namespace &&
- wild_match (name, name_len, SYMBOL_LINKAGE_NAME (psym)))
- return psym;
- }
- return NULL;
- }
- else
- {
- if (global)
- {
- int U;
- i = 0;
- U = length - 1;
- while (U - i > 4)
- {
- int M = (U + i) >> 1;
- struct partial_symbol *psym = start[M];
- if (SYMBOL_LINKAGE_NAME (psym)[0] < name[0])
- i = M + 1;
- else if (SYMBOL_LINKAGE_NAME (psym)[0] > name[0])
- U = M - 1;
- else if (strcmp (SYMBOL_LINKAGE_NAME (psym), name) < 0)
- i = M + 1;
- else
- U = M;
- }
- }
- else
- i = 0;
+/* FIXME: The next two routines belong in symtab.c */
- while (i < length)
- {
- struct partial_symbol *psym = start[i];
+static void restore_language (void* lang)
+{
+ set_language ((enum language) lang);
+}
- if (SYMBOL_DOMAIN (psym) == namespace)
- {
- int cmp = strncmp (name, SYMBOL_LINKAGE_NAME (psym), name_len);
+/* As for lookup_symbol, but performed as if the current language
+ were LANG. */
- if (cmp < 0)
- {
- if (global)
- break;
- }
- else if (cmp == 0
- && is_name_suffix (SYMBOL_LINKAGE_NAME (psym)
- + name_len))
- return psym;
- }
- i += 1;
- }
+struct symbol *
+lookup_symbol_in_language (const char *name, const struct block *block,
+ domain_enum domain, enum language lang,
+ int *is_a_field_of_this, struct symtab **symtab)
+{
+ struct cleanup *old_chain
+ = make_cleanup (restore_language, (void*) current_language->la_language);
+ struct symbol *result;
+ set_language (lang);
+ result = lookup_symbol (name, block, domain, is_a_field_of_this, symtab);
+ do_cleanups (old_chain);
+ return result;
+}
- if (global)
- {
- int U;
- i = 0;
- U = length - 1;
- while (U - i > 4)
- {
- int M = (U + i) >> 1;
- struct partial_symbol *psym = start[M];
- if (SYMBOL_LINKAGE_NAME (psym)[0] < '_')
- i = M + 1;
- else if (SYMBOL_LINKAGE_NAME (psym)[0] > '_')
- U = M - 1;
- else if (strcmp (SYMBOL_LINKAGE_NAME (psym), "_ada_") < 0)
- i = M + 1;
- else
- U = M;
- }
- }
- else
- i = 0;
+/* True if TYPE is definitely an artificial type supplied to a symbol
+ for which no debugging information was given in the symbol file. */
- while (i < length)
- {
- struct partial_symbol *psym = start[i];
+static int
+is_nondebugging_type (struct type *type)
+{
+ char *name = ada_type_name (type);
+ return (name != NULL && strcmp (name, "<variable, no debug info>") == 0);
+}
- if (SYMBOL_DOMAIN (psym) == namespace)
- {
- int cmp;
+/* Remove any non-debugging symbols in SYMS[0 .. NSYMS-1] that definitely
+ duplicate other symbols in the list (The only case I know of where
+ this happens is when object files containing stabs-in-ecoff are
+ linked with files containing ordinary ecoff debugging symbols (or no
+ debugging symbols)). Modifies SYMS to squeeze out deleted entries.
+ Returns the number of items in the modified list. */
- cmp = (int) '_' - (int) SYMBOL_LINKAGE_NAME (psym)[0];
- if (cmp == 0)
- {
- cmp = strncmp ("_ada_", SYMBOL_LINKAGE_NAME (psym), 5);
- if (cmp == 0)
- cmp = strncmp (name, SYMBOL_LINKAGE_NAME (psym) + 5,
- name_len);
- }
+static int
+remove_extra_symbols (struct ada_symbol_info *syms, int nsyms)
+{
+ int i, j;
- if (cmp < 0)
+ i = 0;
+ while (i < nsyms)
+ {
+ if (SYMBOL_LINKAGE_NAME (syms[i].sym) != NULL
+ && SYMBOL_CLASS (syms[i].sym) == LOC_STATIC
+ && is_nondebugging_type (SYMBOL_TYPE (syms[i].sym)))
+ {
+ for (j = 0; j < nsyms; j += 1)
+ {
+ if (i != j
+ && SYMBOL_LINKAGE_NAME (syms[j].sym) != NULL
+ && strcmp (SYMBOL_LINKAGE_NAME (syms[i].sym),
+ SYMBOL_LINKAGE_NAME (syms[j].sym)) == 0
+ && SYMBOL_CLASS (syms[i].sym) == SYMBOL_CLASS (syms[j].sym)
+ && SYMBOL_VALUE_ADDRESS (syms[i].sym)
+ == SYMBOL_VALUE_ADDRESS (syms[j].sym))
{
- if (global)
- break;
+ int k;
+ for (k = i + 1; k < nsyms; k += 1)
+ syms[k - 1] = syms[k];
+ nsyms -= 1;
+ goto NextSymbol;
}
- else if (cmp == 0
- && is_name_suffix (SYMBOL_LINKAGE_NAME (psym)
- + name_len + 5))
- return psym;
}
- i += 1;
}
+ i += 1;
+ NextSymbol:
+ ;
}
- return NULL;
+ return nsyms;
}
-/* Find a symbol table containing symbol SYM or NULL if none. */
+/* Given a type that corresponds to a renaming entity, use the type name
+ to extract the scope (package name or function name, fully qualified,
+ and following the GNAT encoding convention) where this renaming has been
+ defined. The string returned needs to be deallocated after use. */
-static struct symtab *
-symtab_for_sym (struct symbol *sym)
+static char *
+xget_renaming_scope (struct type *renaming_type)
{
- struct symtab *s;
- struct objfile *objfile;
- struct block *b;
- struct symbol *tmp_sym;
- struct dict_iterator iter;
- int j;
+ /* The renaming types adhere to the following convention:
+ <scope>__<rename>___<XR extension>.
+ So, to extract the scope, we search for the "___XR" extension,
+ and then backtrack until we find the first "__". */
+
+ const char *name = type_name_no_tag (renaming_type);
+ char *suffix = strstr (name, "___XR");
+ char *last;
+ int scope_len;
+ char *scope;
- ALL_SYMTABS (objfile, s)
- {
- switch (SYMBOL_CLASS (sym))
- {
- case LOC_CONST:
- case LOC_STATIC:
- case LOC_TYPEDEF:
- case LOC_REGISTER:
- case LOC_LABEL:
- case LOC_BLOCK:
- case LOC_CONST_BYTES:
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
- ALL_BLOCK_SYMBOLS (b, iter, tmp_sym) if (sym == tmp_sym)
- return s;
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
- ALL_BLOCK_SYMBOLS (b, iter, tmp_sym) if (sym == tmp_sym)
- return s;
- break;
- default:
- break;
- }
- switch (SYMBOL_CLASS (sym))
- {
- case LOC_REGISTER:
- case LOC_ARG:
- case LOC_REF_ARG:
- case LOC_REGPARM:
- case LOC_REGPARM_ADDR:
- case LOC_LOCAL:
- case LOC_TYPEDEF:
- case LOC_LOCAL_ARG:
- case LOC_BASEREG:
- case LOC_BASEREG_ARG:
- case LOC_COMPUTED:
- case LOC_COMPUTED_ARG:
- for (j = FIRST_LOCAL_BLOCK;
- j < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (s)); j += 1)
- {
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), j);
- ALL_BLOCK_SYMBOLS (b, iter, tmp_sym) if (sym == tmp_sym)
- return s;
- }
- break;
- default:
- break;
- }
- }
- return NULL;
-}
-
-/* Return a minimal symbol matching NAME according to Ada decoding
- rules. Returns NULL if there is no such minimal symbol. Names
- prefixed with "standard__" are handled specially: "standard__" is
- first stripped off, and only static and global symbols are searched. */
-
-struct minimal_symbol *
-ada_lookup_simple_minsym (const char *name)
-{
- struct objfile *objfile;
- struct minimal_symbol *msymbol;
- int wild_match;
-
- if (strncmp (name, "standard__", sizeof ("standard__") - 1) == 0)
- {
- name += sizeof ("standard__") - 1;
- wild_match = 0;
- }
- else
- wild_match = (strstr (name, "__") == NULL);
+ /* Now, backtrack a bit until we find the first "__". Start looking
+ at suffix - 3, as the <rename> part is at least one character long. */
- ALL_MSYMBOLS (objfile, msymbol)
- {
- if (ada_match_name (SYMBOL_LINKAGE_NAME (msymbol), name, wild_match)
- && MSYMBOL_TYPE (msymbol) != mst_solib_trampoline)
- return msymbol;
- }
+ for (last = suffix - 3; last > name; last--)
+ if (last[0] == '_' && last[1] == '_')
+ break;
+
+ /* Make a copy of scope and return it. */
- return NULL;
-}
+ scope_len = last - name;
+ scope = (char *) xmalloc ((scope_len + 1) * sizeof (char));
-/* Return up minimal symbol for NAME, folded and encoded according to
- Ada conventions, or NULL if none. The last two arguments are ignored. */
+ strncpy (scope, name, scope_len);
+ scope[scope_len] = '\0';
-static struct minimal_symbol *
-ada_lookup_minimal_symbol (const char *name, const char *sfile,
- struct objfile *objf)
-{
- return ada_lookup_simple_minsym (ada_encode (name));
+ return scope;
}
-/* For all subprograms that statically enclose the subprogram of the
- selected frame, add symbols matching identifier NAME in DOMAIN
- and their blocks to the list of data in OBSTACKP, as for
- ada_add_block_symbols (q.v.). If WILD, treat as NAME with a
- wildcard prefix. */
+/* Return nonzero if NAME corresponds to a package name. */
-static void
-add_symbols_from_enclosing_procs (struct obstack *obstackp,
- const char *name, domain_enum namespace,
- int wild_match)
+static int
+is_package_name (const char *name)
{
-#ifdef HAVE_ADD_SYMBOLS_FROM_ENCLOSING_PROCS
- /* Use a heuristic to find the frames of enclosing subprograms: treat the
- pointer-sized value at location 0 from the local-variable base of a
- frame as a static link, and then search up the call stack for a
- frame with that same local-variable base. */
- static struct symbol static_link_sym;
- static struct symbol *static_link;
- struct value *target_link_val;
-
- struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
- struct frame_info *frame;
+ /* Here, We take advantage of the fact that no symbols are generated
+ for packages, while symbols are generated for each function.
+ So the condition for NAME represent a package becomes equivalent
+ to NAME not existing in our list of symbols. There is only one
+ small complication with library-level functions (see below). */
- if (! target_has_stack)
- return;
+ char *fun_name;
+
+ /* If it is a function that has not been defined at library level,
+ then we should be able to look it up in the symbols. */
+ if (standard_lookup (name, NULL, VAR_DOMAIN) != NULL)
+ return 0;
- if (static_link == NULL)
- {
- /* Initialize the local variable symbol that stands for the
- static link (when there is one). */
- static_link = &static_link_sym;
- SYMBOL_LINKAGE_NAME (static_link) = "";
- SYMBOL_LANGUAGE (static_link) = language_unknown;
- SYMBOL_CLASS (static_link) = LOC_LOCAL;
- SYMBOL_DOMAIN (static_link) = VAR_DOMAIN;
- SYMBOL_TYPE (static_link) = lookup_pointer_type (builtin_type_void);
- SYMBOL_VALUE (static_link) =
- -(long) TYPE_LENGTH (SYMBOL_TYPE (static_link));
- }
+ /* Library-level function names start with "_ada_". See if function
+ "_ada_" followed by NAME can be found. */
- frame = get_selected_frame ();
- if (frame == NULL
- || inside_main_func (get_frame_address_in_block (frame)))
- return;
+ /* Do a quick check that NAME does not contain "__", since library-level
+ functions names can not contain "__" in them. */
+ if (strstr (name, "__") != NULL)
+ return 0;
- target_link_val = read_var_value (static_link, frame);
- while (target_link_val != NULL
- && num_defns_collected (obstackp) == 0
- && frame_relative_level (frame) <= MAX_ENCLOSING_FRAME_LEVELS)
- {
- CORE_ADDR target_link = value_as_address (target_link_val);
+ fun_name = (char *) alloca (strlen (name) + 5 + 1);
+ xasprintf (&fun_name, "_ada_%s", name);
- frame = get_prev_frame (frame);
- if (frame == NULL)
- break;
+ return (standard_lookup (fun_name, NULL, VAR_DOMAIN) == NULL);
+}
- if (get_frame_locals_address (frame) == target_link)
- {
- struct block *block;
-
- QUIT;
+/* Return nonzero if SYM corresponds to a renaming entity that is
+ visible from FUNCTION_NAME. */
- block = get_frame_block (frame, 0);
- while (block != NULL && block_function (block) != NULL
- && num_defns_collected (obstackp) == 0)
- {
- QUIT;
+static int
+renaming_is_visible (const struct symbol *sym, char *function_name)
+{
+ char *scope = xget_renaming_scope (SYMBOL_TYPE (sym));
- ada_add_block_symbols (obstackp, block, name, namespace,
- NULL, NULL, wild_match);
-
- block = BLOCK_SUPERBLOCK (block);
- }
- }
- }
+ make_cleanup (xfree, scope);
- do_cleanups (old_chain);
-#endif
-}
+ /* If the rename has been defined in a package, then it is visible. */
+ if (is_package_name (scope))
+ return 1;
-/* FIXME: The next two routines belong in symtab.c */
+ /* Check that the rename is in the current function scope by checking
+ that its name starts with SCOPE. */
+
+ /* If the function name starts with "_ada_", it means that it is
+ a library-level function. Strip this prefix before doing the
+ comparison, as the encoding for the renaming does not contain
+ this prefix. */
+ if (strncmp (function_name, "_ada_", 5) == 0)
+ function_name += 5;
-static void restore_language (void* lang)
-{
- set_language ((enum language) lang);
+ return (strncmp (function_name, scope, strlen (scope)) == 0);
}
-/* As for lookup_symbol, but performed as if the current language
- were LANG. */
-
-struct symbol *
-lookup_symbol_in_language (const char *name, const struct block *block,
- domain_enum domain, enum language lang,
- int *is_a_field_of_this, struct symtab **symtab)
-{
- struct cleanup *old_chain
- = make_cleanup (restore_language, (void*) current_language->la_language);
- struct symbol *result;
- set_language (lang);
- result = lookup_symbol (name, block, domain, is_a_field_of_this, symtab);
- do_cleanups (old_chain);
- return result;
-}
+/* Iterates over the SYMS list and remove any entry that corresponds to
+ a renaming entity that is not visible from the function associated
+ with CURRENT_BLOCK.
+
+ Rationale:
+ GNAT emits a type following a specified encoding for each renaming
+ entity. Unfortunately, STABS currently does not support the definition
+ of types that are local to a given lexical block, so all renamings types
+ are emitted at library level. As a consequence, if an application
+ contains two renaming entities using the same name, and a user tries to
+ print the value of one of these entities, the result of the ada symbol
+ lookup will also contain the wrong renaming type.
-/* True if TYPE is definitely an artificial type supplied to a symbol
- for which no debugging information was given in the symbol file. */
+ This function partially covers for this limitation by attempting to
+ remove from the SYMS list renaming symbols that should be visible
+ from CURRENT_BLOCK. However, there does not seem be a 100% reliable
+ method with the current information available. The implementation
+ below has a couple of limitations (FIXME: brobecker-2003-05-12):
+
+ - When the user tries to print a rename in a function while there
+ is another rename entity defined in a package: Normally, the
+ rename in the function has precedence over the rename in the
+ package, so the latter should be removed from the list. This is
+ currently not the case.
+
+ - This function will incorrectly remove valid renames if
+ the CURRENT_BLOCK corresponds to a function which symbol name
+ has been changed by an "Export" pragma. As a consequence,
+ the user will be unable to print such rename entities. */
static int
-is_nondebugging_type (struct type *type)
-{
- char *name = ada_type_name (type);
- return (name != NULL && strcmp (name, "<variable, no debug info>") == 0);
-}
-
-/* Remove any non-debugging symbols in SYMS[0 .. NSYMS-1] that definitely
- duplicate other symbols in the list (The only case I know of where
- this happens is when object files containing stabs-in-ecoff are
- linked with files containing ordinary ecoff debugging symbols (or no
- debugging symbols)). Modifies SYMS to squeeze out deleted entries.
- Returns the number of items in the modified list. */
-
-static int
-remove_extra_symbols (struct ada_symbol_info *syms, int nsyms)
-{
- int i, j;
-
- i = 0;
- while (i < nsyms)
- {
- if (SYMBOL_LINKAGE_NAME (syms[i].sym) != NULL
- && SYMBOL_CLASS (syms[i].sym) == LOC_STATIC
- && is_nondebugging_type (SYMBOL_TYPE (syms[i].sym)))
- {
- for (j = 0; j < nsyms; j += 1)
- {
- if (i != j
- && SYMBOL_LINKAGE_NAME (syms[j].sym) != NULL
- && strcmp (SYMBOL_LINKAGE_NAME (syms[i].sym),
- SYMBOL_LINKAGE_NAME (syms[j].sym)) == 0
- && SYMBOL_CLASS (syms[i].sym) == SYMBOL_CLASS (syms[j].sym)
- && SYMBOL_VALUE_ADDRESS (syms[i].sym)
- == SYMBOL_VALUE_ADDRESS (syms[j].sym))
- {
- int k;
- for (k = i + 1; k < nsyms; k += 1)
- syms[k - 1] = syms[k];
- nsyms -= 1;
- goto NextSymbol;
- }
- }
- }
- i += 1;
- NextSymbol:
- ;
- }
- return nsyms;
-}
-
-/* Given a type that corresponds to a renaming entity, use the type name
- to extract the scope (package name or function name, fully qualified,
- and following the GNAT encoding convention) where this renaming has been
- defined. The string returned needs to be deallocated after use. */
-
-static char *
-xget_renaming_scope (struct type *renaming_type)
-{
- /* The renaming types adhere to the following convention:
- <scope>__<rename>___<XR extension>.
- So, to extract the scope, we search for the "___XR" extension,
- and then backtrack until we find the first "__". */
-
- const char *name = type_name_no_tag (renaming_type);
- char *suffix = strstr (name, "___XR");
- char *last;
- int scope_len;
- char *scope;
-
- /* Now, backtrack a bit until we find the first "__". Start looking
- at suffix - 3, as the <rename> part is at least one character long. */
-
- for (last = suffix - 3; last > name; last--)
- if (last[0] == '_' && last[1] == '_')
- break;
-
- /* Make a copy of scope and return it. */
-
- scope_len = last - name;
- scope = (char *) xmalloc ((scope_len + 1) * sizeof (char));
-
- strncpy (scope, name, scope_len);
- scope[scope_len] = '\0';
-
- return scope;
-}
-
-/* Return nonzero if NAME corresponds to a package name. */
-
-static int
-is_package_name (const char *name)
-{
- /* Here, We take advantage of the fact that no symbols are generated
- for packages, while symbols are generated for each function.
- So the condition for NAME represent a package becomes equivalent
- to NAME not existing in our list of symbols. There is only one
- small complication with library-level functions (see below). */
-
- char *fun_name;
-
- /* If it is a function that has not been defined at library level,
- then we should be able to look it up in the symbols. */
- if (standard_lookup (name, NULL, VAR_DOMAIN) != NULL)
- return 0;
-
- /* Library-level function names start with "_ada_". See if function
- "_ada_" followed by NAME can be found. */
-
- /* Do a quick check that NAME does not contain "__", since library-level
- functions names can not contain "__" in them. */
- if (strstr (name, "__") != NULL)
- return 0;
-
- fun_name = (char *) alloca (strlen (name) + 5 + 1);
- xasprintf (&fun_name, "_ada_%s", name);
-
- return (standard_lookup (fun_name, NULL, VAR_DOMAIN) == NULL);
-}
-
-/* Return nonzero if SYM corresponds to a renaming entity that is
- visible from FUNCTION_NAME. */
-
-static int
-renaming_is_visible (const struct symbol *sym, char *function_name)
-{
- char *scope = xget_renaming_scope (SYMBOL_TYPE (sym));
-
- make_cleanup (xfree, scope);
-
- /* If the rename has been defined in a package, then it is visible. */
- if (is_package_name (scope))
- return 1;
-
- /* Check that the rename is in the current function scope by checking
- that its name starts with SCOPE. */
-
- /* If the function name starts with "_ada_", it means that it is
- a library-level function. Strip this prefix before doing the
- comparison, as the encoding for the renaming does not contain
- this prefix. */
- if (strncmp (function_name, "_ada_", 5) == 0)
- function_name += 5;
-
- return (strncmp (function_name, scope, strlen (scope)) == 0);
-}
-
-/* Iterates over the SYMS list and remove any entry that corresponds to
- a renaming entity that is not visible from the function associated
- with CURRENT_BLOCK.
-
- Rationale:
- GNAT emits a type following a specified encoding for each renaming
- entity. Unfortunately, STABS currently does not support the definition
- of types that are local to a given lexical block, so all renamings types
- are emitted at library level. As a consequence, if an application
- contains two renaming entities using the same name, and a user tries to
- print the value of one of these entities, the result of the ada symbol
- lookup will also contain the wrong renaming type.
-
- This function partially covers for this limitation by attempting to
- remove from the SYMS list renaming symbols that should be visible
- from CURRENT_BLOCK. However, there does not seem be a 100% reliable
- method with the current information available. The implementation
- below has a couple of limitations (FIXME: brobecker-2003-05-12):
-
- - When the user tries to print a rename in a function while there
- is another rename entity defined in a package: Normally, the
- rename in the function has precedence over the rename in the
- package, so the latter should be removed from the list. This is
- currently not the case.
-
- - This function will incorrectly remove valid renames if
- the CURRENT_BLOCK corresponds to a function which symbol name
- has been changed by an "Export" pragma. As a consequence,
- the user will be unable to print such rename entities. */
-
-static int
-remove_out_of_scope_renamings (struct ada_symbol_info *syms,
- int nsyms,
- struct block *current_block)
+remove_out_of_scope_renamings (struct ada_symbol_info *syms,
+ int nsyms,
+ struct block *current_block)
{
struct symbol *current_function;
char *current_function_name;
name += 1;
name_len -= 1;
}
- }
-
- return 0;
-}
+ }
+
+ return 0;
+}
+
+
+/* Add symbols from BLOCK matching identifier NAME in DOMAIN to
+ vector *defn_symbols, updating the list of symbols in OBSTACKP
+ (if necessary). If WILD, treat as NAME with a wildcard prefix.
+ OBJFILE is the section containing BLOCK.
+ SYMTAB is recorded with each symbol added. */
+
+static void
+ada_add_block_symbols (struct obstack *obstackp,
+ struct block *block, const char *name,
+ domain_enum domain, struct objfile *objfile,
+ struct symtab *symtab, int wild)
+{
+ struct dict_iterator iter;
+ int name_len = strlen (name);
+ /* A matching argument symbol, if any. */
+ struct symbol *arg_sym;
+ /* Set true when we find a matching non-argument symbol. */
+ int found_sym;
+ struct symbol *sym;
+
+ arg_sym = NULL;
+ found_sym = 0;
+ if (wild)
+ {
+ struct symbol *sym;
+ ALL_BLOCK_SYMBOLS (block, iter, sym)
+ {
+ if (SYMBOL_DOMAIN (sym) == domain &&
+ wild_match (name, name_len, SYMBOL_LINKAGE_NAME (sym)))
+ {
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_ARG:
+ case LOC_LOCAL_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_BASEREG_ARG:
+ case LOC_COMPUTED_ARG:
+ arg_sym = sym;
+ break;
+ case LOC_UNRESOLVED:
+ continue;
+ default:
+ found_sym = 1;
+ add_defn_to_vec (obstackp,
+ fixup_symbol_section (sym, objfile),
+ block, symtab);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ ALL_BLOCK_SYMBOLS (block, iter, sym)
+ {
+ if (SYMBOL_DOMAIN (sym) == domain)
+ {
+ int cmp = strncmp (name, SYMBOL_LINKAGE_NAME (sym), name_len);
+ if (cmp == 0
+ && is_name_suffix (SYMBOL_LINKAGE_NAME (sym) + name_len))
+ {
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_ARG:
+ case LOC_LOCAL_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_BASEREG_ARG:
+ case LOC_COMPUTED_ARG:
+ arg_sym = sym;
+ break;
+ case LOC_UNRESOLVED:
+ break;
+ default:
+ found_sym = 1;
+ add_defn_to_vec (obstackp,
+ fixup_symbol_section (sym, objfile),
+ block, symtab);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (!found_sym && arg_sym != NULL)
+ {
+ add_defn_to_vec (obstackp,
+ fixup_symbol_section (arg_sym, objfile),
+ block, symtab);
+ }
+
+ if (!wild)
+ {
+ arg_sym = NULL;
+ found_sym = 0;
+
+ ALL_BLOCK_SYMBOLS (block, iter, sym)
+ {
+ if (SYMBOL_DOMAIN (sym) == domain)
+ {
+ int cmp;
+
+ cmp = (int) '_' - (int) SYMBOL_LINKAGE_NAME (sym)[0];
+ if (cmp == 0)
+ {
+ cmp = strncmp ("_ada_", SYMBOL_LINKAGE_NAME (sym), 5);
+ if (cmp == 0)
+ cmp = strncmp (name, SYMBOL_LINKAGE_NAME (sym) + 5,
+ name_len);
+ }
+
+ if (cmp == 0
+ && is_name_suffix (SYMBOL_LINKAGE_NAME (sym) + name_len + 5))
+ {
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_ARG:
+ case LOC_LOCAL_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_BASEREG_ARG:
+ case LOC_COMPUTED_ARG:
+ arg_sym = sym;
+ break;
+ case LOC_UNRESOLVED:
+ break;
+ default:
+ found_sym = 1;
+ add_defn_to_vec (obstackp,
+ fixup_symbol_section (sym, objfile),
+ block, symtab);
+ break;
+ }
+ }
+ }
+ end_loop2: ;
+ }
+
+ /* NOTE: This really shouldn't be needed for _ada_ symbols.
+ They aren't parameters, right? */
+ if (!found_sym && arg_sym != NULL)
+ {
+ add_defn_to_vec (obstackp,
+ fixup_symbol_section (arg_sym, objfile),
+ block, symtab);
+ }
+ }
+}
+\f
+#ifdef GNAT_GDB
+
+ /* Symbol Completion */
+
+/* If SYM_NAME is a completion candidate for TEXT, return this symbol
+ name in a form that's appropriate for the completion. The result
+ does not need to be deallocated, but is only good until the next call.
+
+ TEXT_LEN is equal to the length of TEXT.
+ Perform a wild match if WILD_MATCH is set.
+ ENCODED should be set if TEXT represents the start of a symbol name
+ in its encoded form. */
+
+static const char *
+symbol_completion_match (const char *sym_name,
+ const char *text, int text_len,
+ int wild_match, int encoded)
+{
+ char *result;
+ const int verbatim_match = (text[0] == '<');
+ int match = 0;
+
+ if (verbatim_match)
+ {
+ /* Strip the leading angle bracket. */
+ text = text + 1;
+ text_len--;
+ }
+
+ /* First, test against the fully qualified name of the symbol. */
+
+ if (strncmp (sym_name, text, text_len) == 0)
+ match = 1;
+
+ if (match && !encoded)
+ {
+ /* One needed check before declaring a positive match is to verify
+ that iff we are doing a verbatim match, the decoded version
+ of the symbol name starts with '<'. Otherwise, this symbol name
+ is not a suitable completion. */
+ const char *sym_name_copy = sym_name;
+ int has_angle_bracket;
+
+ sym_name = ada_decode (sym_name);
+ has_angle_bracket = (sym_name [0] == '<');
+ match = (has_angle_bracket == verbatim_match);
+ sym_name = sym_name_copy;
+ }
+
+ if (match && !verbatim_match)
+ {
+ /* When doing non-verbatim match, another check that needs to
+ be done is to verify that the potentially matching symbol name
+ does not include capital letters, because the ada-mode would
+ not be able to understand these symbol names without the
+ angle bracket notation. */
+ const char *tmp;
+
+ for (tmp = sym_name; *tmp != '\0' && !isupper (*tmp); tmp++);
+ if (*tmp != '\0')
+ match = 0;
+ }
+
+ /* Second: Try wild matching... */
+
+ if (!match && wild_match)
+ {
+ /* Since we are doing wild matching, this means that TEXT
+ may represent an unqualified symbol name. We therefore must
+ also compare TEXT against the unqualified name of the symbol. */
+ sym_name = ada_unqualified_name (ada_decode (sym_name));
+
+ if (strncmp (sym_name, text, text_len) == 0)
+ match = 1;
+ }
+
+ /* Finally: If we found a mach, prepare the result to return. */
+
+ if (!match)
+ return NULL;
+
+ if (verbatim_match)
+ sym_name = add_angle_brackets (sym_name);
+
+ if (!encoded)
+ sym_name = ada_decode (sym_name);
+
+ return sym_name;
+}
+
+/* A companion function to ada_make_symbol_completion_list().
+ Check if SYM_NAME represents a symbol which name would be suitable
+ to complete TEXT (TEXT_LEN is the length of TEXT), in which case
+ it is appended at the end of the given string vector SV.
+
+ ORIG_TEXT is the string original string from the user command
+ that needs to be completed. WORD is the entire command on which
+ completion should be performed. These two parameters are used to
+ determine which part of the symbol name should be added to the
+ completion vector.
+ if WILD_MATCH is set, then wild matching is performed.
+ ENCODED should be set if TEXT represents a symbol name in its
+ encoded formed (in which case the completion should also be
+ encoded). */
+
+static void
+symbol_completion_add (struct string_vector *sv,
+ const char *sym_name,
+ const char *text, int text_len,
+ const char *orig_text, const char *word,
+ int wild_match, int encoded)
+{
+ const char *match = symbol_completion_match (sym_name, text, text_len,
+ wild_match, encoded);
+ char *completion;
+
+ if (match == NULL)
+ return;
+
+ /* We found a match, so add the appropriate completion to the given
+ string vector. */
+
+ if (word == orig_text)
+ {
+ completion = xmalloc (strlen (match) + 5);
+ strcpy (completion, match);
+ }
+ else if (word > orig_text)
+ {
+ /* Return some portion of sym_name. */
+ completion = xmalloc (strlen (match) + 5);
+ strcpy (completion, match + (word - orig_text));
+ }
+ else
+ {
+ /* Return some of ORIG_TEXT plus sym_name. */
+ completion = xmalloc (strlen (match) + (orig_text - word) + 5);
+ strncpy (completion, word, orig_text - word);
+ completion[orig_text - word] = '\0';
+ strcat (completion, match);
+ }
+
+ string_vector_append (sv, completion);
+}
+
+/* Return a list of possible symbol names completing TEXT0. The list
+ is NULL terminated. WORD is the entire command on which completion
+ is made. */
+
+char **
+ada_make_symbol_completion_list (const char *text0, const char *word)
+{
+ /* Note: This function is almost a copy of make_symbol_completion_list(),
+ except it has been adapted for Ada. It is somewhat of a shame to
+ duplicate so much code, but we don't really have the infrastructure
+ yet to develop a language-aware version of he symbol completer... */
+ char *text;
+ int text_len;
+ int wild_match;
+ int encoded;
+ struct string_vector result = xnew_string_vector (128);
+ struct symbol *sym;
+ struct symtab *s;
+ struct partial_symtab *ps;
+ struct minimal_symbol *msymbol;
+ struct objfile *objfile;
+ struct block *b, *surrounding_static_block = 0;
+ int i;
+ struct dict_iterator iter;
+
+ if (text0[0] == '<')
+ {
+ text = xstrdup (text0);
+ make_cleanup (xfree, text);
+ text_len = strlen (text);
+ wild_match = 0;
+ encoded = 1;
+ }
+ else
+ {
+ text = xstrdup (ada_encode (text0));
+ make_cleanup (xfree, text);
+ text_len = strlen (text);
+ for (i = 0; i < text_len; i++)
+ text[i] = tolower (text[i]);
+
+ /* FIXME: brobecker/2003-09-17: When we get rid of ADA_RETAIN_DOTS,
+ we can restrict the wild_match check to searching "__" only. */
+ wild_match = (strstr (text0, "__") == NULL
+ && strchr (text0, '.') == NULL);
+ encoded = (strstr (text0, "__") != NULL);
+ }
+
+ /* First, look at the partial symtab symbols. */
+ ALL_PSYMTABS (objfile, ps)
+ {
+ struct partial_symbol **psym;
+
+ /* If the psymtab's been read in we'll get it when we search
+ through the blockvector. */
+ if (ps->readin)
+ continue;
+
+ for (psym = objfile->global_psymbols.list + ps->globals_offset;
+ psym < (objfile->global_psymbols.list + ps->globals_offset
+ + ps->n_global_syms);
+ psym++)
+ {
+ QUIT;
+ symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (*psym),
+ text, text_len, text0, word,
+ wild_match, encoded);
+ }
+
+ for (psym = objfile->static_psymbols.list + ps->statics_offset;
+ psym < (objfile->static_psymbols.list + ps->statics_offset
+ + ps->n_static_syms);
+ psym++)
+ {
+ QUIT;
+ symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (*psym),
+ text, text_len, text0, word,
+ wild_match, encoded);
+ }
+ }
+ /* At this point scan through the misc symbol vectors and add each
+ symbol you find to the list. Eventually we want to ignore
+ anything that isn't a text symbol (everything else will be
+ handled by the psymtab code above). */
-/* Add symbols from BLOCK matching identifier NAME in DOMAIN to
- vector *defn_symbols, updating the list of symbols in OBSTACKP
- (if necessary). If WILD, treat as NAME with a wildcard prefix.
- OBJFILE is the section containing BLOCK.
- SYMTAB is recorded with each symbol added. */
+ ALL_MSYMBOLS (objfile, msymbol)
+ {
+ QUIT;
+ symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (msymbol),
+ text, text_len, text0, word,
+ wild_match, encoded);
+ }
-static void
-ada_add_block_symbols (struct obstack *obstackp,
- struct block *block, const char *name,
- domain_enum domain, struct objfile *objfile,
- struct symtab *symtab, int wild)
-{
- struct dict_iterator iter;
- int name_len = strlen (name);
- /* A matching argument symbol, if any. */
- struct symbol *arg_sym;
- /* Set true when we find a matching non-argument symbol. */
- int found_sym;
- struct symbol *sym;
+ /* Search upwards from currently selected frame (so that we can
+ complete on local vars. */
- arg_sym = NULL;
- found_sym = 0;
- if (wild)
- {
- struct symbol *sym;
- ALL_BLOCK_SYMBOLS (block, iter, sym)
- {
- if (SYMBOL_DOMAIN (sym) == domain &&
- wild_match (name, name_len, SYMBOL_LINKAGE_NAME (sym)))
- {
- switch (SYMBOL_CLASS (sym))
- {
- case LOC_ARG:
- case LOC_LOCAL_ARG:
- case LOC_REF_ARG:
- case LOC_REGPARM:
- case LOC_REGPARM_ADDR:
- case LOC_BASEREG_ARG:
- case LOC_COMPUTED_ARG:
- arg_sym = sym;
- break;
- case LOC_UNRESOLVED:
- continue;
- default:
- found_sym = 1;
- add_defn_to_vec (obstackp,
- fixup_symbol_section (sym, objfile),
- block, symtab);
- break;
- }
- }
- }
- }
- else
+ for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
{
- ALL_BLOCK_SYMBOLS (block, iter, sym)
+ if (!BLOCK_SUPERBLOCK (b))
+ surrounding_static_block = b; /* For elmin of dups */
+
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
- if (SYMBOL_DOMAIN (sym) == domain)
- {
- int cmp = strncmp (name, SYMBOL_LINKAGE_NAME (sym), name_len);
- if (cmp == 0
- && is_name_suffix (SYMBOL_LINKAGE_NAME (sym) + name_len))
- {
- switch (SYMBOL_CLASS (sym))
- {
- case LOC_ARG:
- case LOC_LOCAL_ARG:
- case LOC_REF_ARG:
- case LOC_REGPARM:
- case LOC_REGPARM_ADDR:
- case LOC_BASEREG_ARG:
- case LOC_COMPUTED_ARG:
- arg_sym = sym;
- break;
- case LOC_UNRESOLVED:
- break;
- default:
- found_sym = 1;
- add_defn_to_vec (obstackp,
- fixup_symbol_section (sym, objfile),
- block, symtab);
- break;
- }
- }
- }
+ symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
+ text, text_len, text0, word,
+ wild_match, encoded);
}
}
- if (!found_sym && arg_sym != NULL)
- {
- add_defn_to_vec (obstackp,
- fixup_symbol_section (arg_sym, objfile),
- block, symtab);
- }
-
- if (!wild)
- {
- arg_sym = NULL;
- found_sym = 0;
+ /* Go through the symtabs and check the externs and statics for
+ symbols which match. */
- ALL_BLOCK_SYMBOLS (block, iter, sym)
- {
- if (SYMBOL_DOMAIN (sym) == domain)
- {
- int cmp;
+ ALL_SYMTABS (objfile, s)
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
+ {
+ symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
+ text, text_len, text0, word,
+ wild_match, encoded);
+ }
+ }
- cmp = (int) '_' - (int) SYMBOL_LINKAGE_NAME (sym)[0];
- if (cmp == 0)
- {
- cmp = strncmp ("_ada_", SYMBOL_LINKAGE_NAME (sym), 5);
- if (cmp == 0)
- cmp = strncmp (name, SYMBOL_LINKAGE_NAME (sym) + 5,
- name_len);
- }
+ ALL_SYMTABS (objfile, s)
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+ /* Don't do this block twice. */
+ if (b == surrounding_static_block)
+ continue;
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
+ {
+ symbol_completion_add (&result, SYMBOL_LINKAGE_NAME (sym),
+ text, text_len, text0, word,
+ wild_match, encoded);
+ }
+ }
- if (cmp == 0
- && is_name_suffix (SYMBOL_LINKAGE_NAME (sym) + name_len + 5))
- {
- switch (SYMBOL_CLASS (sym))
- {
- case LOC_ARG:
- case LOC_LOCAL_ARG:
- case LOC_REF_ARG:
- case LOC_REGPARM:
- case LOC_REGPARM_ADDR:
- case LOC_BASEREG_ARG:
- case LOC_COMPUTED_ARG:
- arg_sym = sym;
- break;
- case LOC_UNRESOLVED:
- break;
- default:
- found_sym = 1;
- add_defn_to_vec (obstackp,
- fixup_symbol_section (sym, objfile),
- block, symtab);
- break;
- }
- }
- }
- end_loop2: ;
- }
+ /* Append the closing NULL entry. */
+ string_vector_append (&result, NULL);
- /* NOTE: This really shouldn't be needed for _ada_ symbols.
- They aren't parameters, right? */
- if (!found_sym && arg_sym != NULL)
- {
- add_defn_to_vec (obstackp,
- fixup_symbol_section (arg_sym, objfile),
- block, symtab);
- }
- }
+ return (result.array);
}
+
+#endif /* GNAT_GDB */
\f
+#ifdef GNAT_GDB
/* Breakpoint-related */
/* Import message from symtab.c. */
return r;
}
-/* If the main procedure is written in Ada, then return its name.
- The result is good until the next call. Return NULL if the main
- procedure doesn't appear to be in Ada. */
-
-char *
-ada_main_name (void)
-{
- struct minimal_symbol *msym;
- CORE_ADDR main_program_name_addr;
- static char main_program_name[1024];
- /* For Ada, the name of the main procedure is stored in a specific
- string constant, generated by the binder. Look for that symbol,
- extract its address, and then read that string. If we didn't find
- that string, then most probably the main procedure is not written
- in Ada. */
- msym = lookup_minimal_symbol (ADA_MAIN_PROGRAM_SYMBOL_NAME, NULL, NULL);
-
- if (msym != NULL)
- {
- main_program_name_addr = SYMBOL_VALUE_ADDRESS (msym);
- if (main_program_name_addr == 0)
- error ("Invalid address for Ada main program name.");
-
- extract_string (main_program_name_addr, main_program_name);
- return main_program_name;
- }
-
- /* The main procedure doesn't seem to be in Ada. */
- return NULL;
-}
-
/* Return type of Ada breakpoint associated with bp_stat:
0 if not an Ada-specific breakpoint, 1 for break on specific exception,
2 for break on unhandled exception, 3 for assert. */
static int
ada_exception_breakpoint_type (bpstat bs)
{
-#ifdef GNAT_GDB
return ((! bs || ! bs->breakpoint_at) ? 0
: bs->breakpoint_at->break_on_exception);
-#else
- return 0;
-#endif
}
/* True iff FRAME is very likely to be that of a function that is
int
ada_print_exception_breakpoint_nontask (struct breakpoint *b)
{
-#ifdef GNAT_GDB
if (b->break_on_exception == 1)
{
if (b->cond_string) /* the breakpoint is on a specific exception. */
else
return 0;
return 1;
-#else
- return 0;
-#endif
}
/* Print task identifier for breakpoint B, if it is an Ada-specific
void
ada_print_exception_breakpoint_task (struct breakpoint *b)
{
-#ifdef GNAT_GDB
if (b->task != 0)
{
ui_out_text (uiout, " task ");
ui_out_field_int (uiout, "task", b->task);
}
-#endif
}
int
}
return arg;
}
+#endif
\f
-
/* Field Access */
/* True if field number FIELD_NUM in struct or union type TYPE is supposed
#ifdef GNAT_GDB
ada_lookup_symbol,
ada_lookup_minimal_symbol,
-#endif
+#endif /* GNAT_GDB */
&ada_exp_descriptor,
parse,
ada_error,
#ifdef GNAT_GDB
ada_translate_error_message, /* Substitute Ada-specific terminology
in errors and warnings. */
-#endif
+#endif /* GNAT_GDB */
LANG_MAGIC
};
deprecated_register_gdbarch_swap (NULL, 0, build_ada_types);
add_language (&ada_language_defn);
+ varsize_limit = 65536;
#ifdef GNAT_GDB
add_show_from_set
(add_set_cmd ("varsize-limit", class_support, var_uinteger,
(char *) &varsize_limit,
"Set maximum bytes in dynamic-sized object.",
&setlist), &showlist);
-#endif
- varsize_limit = 65536;
+ obstack_init (&cache_space);
+#endif /* GNAT_GDB */
obstack_init (&symbol_list_obstack);
- obstack_init (&cache_space);
decoded_names_store = htab_create_alloc_ex
(256, htab_hash_string, (int (*) (const void *, const void *)) streq,