static void output_source_filename (const char *, int *);
-static int find_line_common (struct linetable *, int, int *);
-
-/* This one is used by linespec.c */
-
-char *operator_chars (char *p, char **end);
+static int find_line_common (struct linetable *, int, int *, int);
static struct symbol *lookup_symbol_aux (const char *name,
const struct block *block,
/* */
+/* Non-zero if a file may be known by two different basenames.
+ This is the uncommon case, and significantly slows down gdb.
+ Default set to "off" to not slow down the common case. */
+int basenames_may_differ = 0;
+
/* Allow the user to configure the debugger behavior with respect
to multiple-choice menus when more than one symbol matches during
a symbol lookup. */
const struct block *block_found;
-/* Check for a symtab of a specific name; first in symtabs, then in
- psymtabs. *If* there is no '/' in the name, a match after a '/'
- in the symtab filename will also work. */
+/* Check for a symtab of a specific name by searching some symtabs.
+ This is a helper function for callbacks of iterate_over_symtabs.
-struct symtab *
-lookup_symtab (const char *name)
+ The return value, NAME, FULL_PATH, REAL_PATH, CALLBACK, and DATA
+ are identical to the `map_symtabs_matching_filename' method of
+ quick_symbol_functions.
+
+ FIRST and AFTER_LAST indicate the range of symtabs to search.
+ AFTER_LAST is one past the last symtab to search; NULL means to
+ search until the end of the list. */
+
+int
+iterate_over_some_symtabs (const char *name,
+ const char *full_path,
+ const char *real_path,
+ int (*callback) (struct symtab *symtab,
+ void *data),
+ void *data,
+ struct symtab *first,
+ struct symtab *after_last)
{
- int found;
struct symtab *s = NULL;
- struct objfile *objfile;
- char *real_path = NULL;
- char *full_path = NULL;
+ struct cleanup *cleanup;
+ const char* base_name = lbasename (name);
- /* Here we are interested in canonicalizing an absolute path, not
- absolutizing a relative path. */
- if (IS_ABSOLUTE_PATH (name))
+ for (s = first; s != NULL && s != after_last; s = s->next)
{
- full_path = xfullpath (name);
- make_cleanup (xfree, full_path);
- real_path = gdb_realpath (name);
- make_cleanup (xfree, real_path);
- }
-
-got_symtab:
-
- /* First, search for an exact match. */
+ if (FILENAME_CMP (name, s->filename) == 0)
+ {
+ if (callback (s, data))
+ return 1;
+ }
- ALL_SYMTABS (objfile, s)
- {
- if (FILENAME_CMP (name, s->filename) == 0)
- {
- return s;
- }
+ /* Before we invoke realpath, which can get expensive when many
+ files are involved, do a quick comparison of the basenames. */
+ if (! basenames_may_differ
+ && FILENAME_CMP (base_name, lbasename (s->filename)) != 0)
+ continue;
/* If the user gave us an absolute path, try to find the file in
this symtab and use its absolute path. */
if (fp != NULL && FILENAME_CMP (full_path, fp) == 0)
{
- return s;
+ if (callback (s, data))
+ return 1;
}
}
make_cleanup (xfree, rp);
if (FILENAME_CMP (real_path, rp) == 0)
- {
- return s;
- }
+ {
+ if (callback (s, data))
+ return 1;
+ }
}
}
- }
+ }
/* Now, search for a matching tail (only if name doesn't have any dirs). */
if (lbasename (name) == name)
- ALL_SYMTABS (objfile, s)
{
- if (FILENAME_CMP (lbasename (s->filename), name) == 0)
- return s;
+ for (s = first; s != NULL && s != after_last; s = s->next)
+ {
+ if (FILENAME_CMP (lbasename (s->filename), name) == 0)
+ {
+ if (callback (s, data))
+ return 1;
+ }
+ }
}
+ return 0;
+}
+
+/* Check for a symtab of a specific name; first in symtabs, then in
+ psymtabs. *If* there is no '/' in the name, a match after a '/'
+ in the symtab filename will also work.
+
+ Calls CALLBACK with each symtab that is found and with the supplied
+ DATA. If CALLBACK returns true, the search stops. */
+
+void
+iterate_over_symtabs (const char *name,
+ int (*callback) (struct symtab *symtab,
+ void *data),
+ void *data)
+{
+ struct symtab *s = NULL;
+ struct objfile *objfile;
+ char *real_path = NULL;
+ char *full_path = NULL;
+ struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
+
+ /* Here we are interested in canonicalizing an absolute path, not
+ absolutizing a relative path. */
+ if (IS_ABSOLUTE_PATH (name))
+ {
+ full_path = xfullpath (name);
+ make_cleanup (xfree, full_path);
+ real_path = gdb_realpath (name);
+ make_cleanup (xfree, real_path);
+ }
+
+ ALL_OBJFILES (objfile)
+ {
+ if (iterate_over_some_symtabs (name, full_path, real_path, callback, data,
+ objfile->symtabs, NULL))
+ {
+ do_cleanups (cleanups);
+ return;
+ }
+ }
+
/* Same search rules as above apply here, but now we look thru the
psymtabs. */
- found = 0;
ALL_OBJFILES (objfile)
{
if (objfile->sf
- && objfile->sf->qf->lookup_symtab (objfile, name, full_path, real_path,
- &s))
+ && objfile->sf->qf->map_symtabs_matching_filename (objfile,
+ name,
+ full_path,
+ real_path,
+ callback,
+ data))
{
- found = 1;
- break;
+ do_cleanups (cleanups);
+ return;
}
}
- if (s != NULL)
- return s;
- if (!found)
- return NULL;
+ do_cleanups (cleanups);
+}
+
+/* The callback function used by lookup_symtab. */
+
+static int
+lookup_symtab_callback (struct symtab *symtab, void *data)
+{
+ struct symtab **result_ptr = data;
+
+ *result_ptr = symtab;
+ return 1;
+}
+
+/* A wrapper for iterate_over_symtabs that returns the first matching
+ symtab, or NULL. */
+
+struct symtab *
+lookup_symtab (const char *name)
+{
+ struct symtab *result = NULL;
- /* At this point, we have located the psymtab for this file, but
- the conversion to a symtab has failed. This usually happens
- when we are looking up an include file. In this case,
- PSYMTAB_TO_SYMTAB doesn't return a symtab, even though one has
- been created. So, we need to run through the symtabs again in
- order to find the file.
- XXX - This is a crock, and should be fixed inside of the the
- symbol parsing routines. */
- goto got_symtab;
+ iterate_over_symtabs (name, lookup_symtab_callback, &result);
+ return result;
}
+
\f
/* Mangle a GDB method stub type. This actually reassembles the pieces of the
full method name, which consist of the class name (from T), the unadorned
struct fn_field *f = TYPE_FN_FIELDLIST1 (type, method_id);
struct fn_field *method = &f[signature_id];
char *field_name = TYPE_FN_FIELDLIST_NAME (type, method_id);
- char *physname = TYPE_FN_FIELD_PHYSNAME (f, signature_id);
+ const char *physname = TYPE_FN_FIELD_PHYSNAME (f, signature_id);
char *newname = type_name_no_tag (type);
/* Does the form of physname indicate that it is the full mangled name
|| gsymbol->language == language_auto)
{
demangled =
- cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
+ cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
if (demangled != NULL)
{
gsymbol->language = language_cplus;
return sym;
}
-/* Find the definition for a specified symbol name NAME
- in domain DOMAIN, visible from lexical block BLOCK.
- Returns the struct symbol pointer, or zero if no symbol is found.
- C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if
- NAME is a field of the current implied argument `this'. If so set
- *IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
- BLOCK_FOUND is set to the block in which NAME is found (in the case of
- a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
+/* Compute the demangled form of NAME as used by the various symbol
+ lookup functions. The result is stored in *RESULT_NAME. Returns a
+ cleanup which can be used to clean up the result.
+
+ For Ada, this function just sets *RESULT_NAME to NAME, unmodified.
+ Normally, Ada symbol lookups are performed using the encoded name
+ rather than the demangled name, and so it might seem to make sense
+ for this function to return an encoded version of NAME.
+ Unfortunately, we cannot do this, because this function is used in
+ circumstances where it is not appropriate to try to encode NAME.
+ For instance, when displaying the frame info, we demangle the name
+ of each parameter, and then perform a symbol lookup inside our
+ function using that demangled name. In Ada, certain functions
+ have internally-generated parameters whose name contain uppercase
+ characters. Encoding those name would result in those uppercase
+ characters to become lowercase, and thus cause the symbol lookup
+ to fail. */
-/* This function has a bunch of loops in it and it would seem to be
- attractive to put in some QUIT's (though I'm not really sure
- whether it can run long enough to be really important). But there
- are a few calls for which it would appear to be bad news to quit
- out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c. (Note
- that there is C++ code below which can error(), but that probably
- doesn't affect these calls since they are looking for a known
- variable and thus can probably assume it will never hit the C++
- code). */
-
-struct symbol *
-lookup_symbol_in_language (const char *name, const struct block *block,
- const domain_enum domain, enum language lang,
- int *is_a_field_of_this)
+struct cleanup *
+demangle_for_lookup (const char *name, enum language lang,
+ const char **result_name)
{
char *demangled_name = NULL;
const char *modified_name = NULL;
- struct symbol *returnval;
struct cleanup *cleanup = make_cleanup (null_cleanup, 0);
modified_name = name;
}
}
- if (case_sensitivity == case_sensitive_off)
- {
- char *copy;
- int len, i;
-
- len = strlen (name);
- copy = (char *) alloca (len + 1);
- for (i= 0; i < len; i++)
- copy[i] = tolower (name[i]);
- copy[len] = 0;
- modified_name = copy;
- }
+ *result_name = modified_name;
+ return cleanup;
+}
+
+/* Find the definition for a specified symbol name NAME
+ in domain DOMAIN, visible from lexical block BLOCK.
+ Returns the struct symbol pointer, or zero if no symbol is found.
+ C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if
+ NAME is a field of the current implied argument `this'. If so set
+ *IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
+ BLOCK_FOUND is set to the block in which NAME is found (in the case of
+ a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
+
+/* This function has a bunch of loops in it and it would seem to be
+ attractive to put in some QUIT's (though I'm not really sure
+ whether it can run long enough to be really important). But there
+ are a few calls for which it would appear to be bad news to quit
+ out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c. (Note
+ that there is C++ code below which can error(), but that probably
+ doesn't affect these calls since they are looking for a known
+ variable and thus can probably assume it will never hit the C++
+ code). */
+
+struct symbol *
+lookup_symbol_in_language (const char *name, const struct block *block,
+ const domain_enum domain, enum language lang,
+ int *is_a_field_of_this)
+{
+ const char *modified_name;
+ struct symbol *returnval;
+ struct cleanup *cleanup = demangle_for_lookup (name, lang, &modified_name);
returnval = lookup_symbol_aux (modified_name, block, domain, lang,
is_a_field_of_this);
is_a_field_of_this);
}
+/* Look up the `this' symbol for LANG in BLOCK. Return the symbol if
+ found, or NULL if not found. */
+
+struct symbol *
+lookup_language_this (const struct language_defn *lang,
+ const struct block *block)
+{
+ if (lang->la_name_of_this == NULL || block == NULL)
+ return NULL;
+
+ while (block)
+ {
+ struct symbol *sym;
+
+ sym = lookup_block_symbol (block, lang->la_name_of_this, VAR_DOMAIN);
+ if (sym != NULL)
+ return sym;
+ if (BLOCK_FUNCTION (block))
+ break;
+ block = BLOCK_SUPERBLOCK (block);
+ }
+
+ return NULL;
+}
+
/* Behave like lookup_symbol 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
langdef = language_def (language);
- if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
- && block != NULL)
+ if (is_a_field_of_this != NULL)
{
- struct symbol *sym = NULL;
- const struct block *function_block = block;
+ struct symbol *sym = lookup_language_this (langdef, block);
- /* 'this' is only defined in the function's block, so find the
- enclosing function block. */
- for (; function_block && !BLOCK_FUNCTION (function_block);
- function_block = BLOCK_SUPERBLOCK (function_block));
-
- if (function_block && !dict_empty (BLOCK_DICT (function_block)))
- sym = lookup_block_symbol (function_block, langdef->la_name_of_this,
- VAR_DOMAIN);
if (sym)
{
struct type *t = sym->type;
}
}
+/* Iterate over the symbols named NAME, matching DOMAIN, starting with
+ BLOCK.
+
+ For each symbol that matches, CALLBACK is called. The symbol and
+ DATA are passed to the callback.
+
+ If CALLBACK returns zero, the iteration ends. Otherwise, the
+ search continues. This function iterates upward through blocks.
+ When the outermost block has been finished, the function
+ returns. */
+
+void
+iterate_over_symbols (const struct block *block, const char *name,
+ const domain_enum domain,
+ int (*callback) (struct symbol *, void *),
+ void *data)
+{
+ while (block)
+ {
+ struct dict_iterator iter;
+ struct symbol *sym;
+
+ for (sym = dict_iter_name_first (BLOCK_DICT (block), name, &iter);
+ sym != NULL;
+ sym = dict_iter_name_next (name, &iter))
+ {
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+ SYMBOL_DOMAIN (sym), domain))
+ {
+ if (!callback (sym, data))
+ return;
+ }
+ }
+
+ block = BLOCK_SUPERBLOCK (block);
+ }
+}
+
/* Find the symtab associated with PC and SECTION. Look through the
psymtabs and read in another symtab if necessary. */
/* First try looking it up in the given symtab. */
best_linetable = LINETABLE (symtab);
best_symtab = symtab;
- best_index = find_line_common (best_linetable, line, &exact);
+ best_index = find_line_common (best_linetable, line, &exact, 0);
if (best_index < 0 || !exact)
{
/* Didn't find an exact match. So we better keep looking for
&& FILENAME_CMP (symtab->fullname, s->fullname) != 0)
continue;
l = LINETABLE (s);
- ind = find_line_common (l, line, &exact);
+ ind = find_line_common (l, line, &exact, 0);
if (ind >= 0)
{
if (exact)
return best_symtab;
}
+
+/* Given SYMTAB, returns all the PCs function in the symtab that
+ exactly match LINE. Returns NULL if there are no exact matches,
+ but updates BEST_ITEM in this case. */
+
+VEC (CORE_ADDR) *
+find_pcs_for_symtab_line (struct symtab *symtab, int line,
+ struct linetable_entry **best_item)
+{
+ int start = 0, ix;
+ struct symbol *previous_function = NULL;
+ VEC (CORE_ADDR) *result = NULL;
+
+ /* First, collect all the PCs that are at this line. */
+ while (1)
+ {
+ int was_exact;
+ int idx;
+
+ idx = find_line_common (LINETABLE (symtab), line, &was_exact, start);
+ if (idx < 0)
+ break;
+
+ if (!was_exact)
+ {
+ struct linetable_entry *item = &LINETABLE (symtab)->item[idx];
+
+ if (*best_item == NULL || item->line < (*best_item)->line)
+ *best_item = item;
+
+ break;
+ }
+
+ VEC_safe_push (CORE_ADDR, result, LINETABLE (symtab)->item[idx].pc);
+ start = idx + 1;
+ }
+
+ return result;
+}
+
\f
/* Set the PC value for a given source file and line number and return true.
Returns zero for invalid line number (and sets the PC to 0).
/* Given a line table and a line number, return the index into the line
table for the pc of the nearest line whose number is >= the specified one.
Return -1 if none is found. The value is >= 0 if it is an index.
+ START is the index at which to start searching the line table.
Set *EXACT_MATCH nonzero if the value returned is an exact match. */
static int
find_line_common (struct linetable *l, int lineno,
- int *exact_match)
+ int *exact_match, int start)
{
int i;
int len;
return -1;
len = l->nitems;
- for (i = 0; i < len; i++)
+ for (i = start; i < len; i++)
{
struct linetable_entry *item = &(l->item[i]);
struct symbol *sym;
struct symtab_and_line start_sal;
struct cleanup *old_chain;
- CORE_ADDR pc;
+ CORE_ADDR pc, saved_pc;
struct obj_section *section;
const char *name;
struct objfile *objfile;
struct gdbarch *gdbarch;
struct block *b, *function_block;
+ int force_skip, skip;
/* Do not change the SAL is PC was specified explicitly. */
if (sal->explicit_pc)
gdbarch = get_objfile_arch (objfile);
- /* If the function is in an unmapped overlay, use its unmapped LMA address,
- so that gdbarch_skip_prologue has something unique to work on. */
- if (section_is_overlay (section) && !section_is_mapped (section))
- pc = overlay_unmapped_address (pc, section);
+ /* Process the prologue in two passes. In the first pass try to skip the
+ prologue (SKIP is true) and verify there is a real need for it (indicated
+ by FORCE_SKIP). If no such reason was found run a second pass where the
+ prologue is not skipped (SKIP is false). */
- /* Skip "first line" of function (which is actually its prologue). */
- pc += gdbarch_deprecated_function_start_offset (gdbarch);
- pc = gdbarch_skip_prologue (gdbarch, pc);
+ skip = 1;
+ force_skip = 1;
- /* For overlays, map pc back into its mapped VMA range. */
- pc = overlay_mapped_address (pc, section);
+ /* Be conservative - allow direct PC (without skipping prologue) only if we
+ have proven the CU (Compilation Unit) supports it. sal->SYMTAB does not
+ have to be set by the caller so we use SYM instead. */
+ if (sym && SYMBOL_SYMTAB (sym)->locations_valid)
+ force_skip = 0;
- /* Calculate line number. */
- start_sal = find_pc_sect_line (pc, section, 0);
-
- /* Check if gdbarch_skip_prologue left us in mid-line, and the next
- line is still part of the same function. */
- if (start_sal.pc != pc
- && (sym? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end
- && start_sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
- : (lookup_minimal_symbol_by_pc_section (start_sal.end, section)
- == lookup_minimal_symbol_by_pc_section (pc, section))))
+ saved_pc = pc;
+ do
{
- /* First pc of next line */
- pc = start_sal.end;
- /* Recalculate the line number (might not be N+1). */
- start_sal = find_pc_sect_line (pc, section, 0);
- }
+ pc = saved_pc;
- /* On targets with executable formats that don't have a concept of
- constructors (ELF with .init has, PE doesn't), gcc emits a call
- to `__main' in `main' between the prologue and before user
- code. */
- if (gdbarch_skip_main_prologue_p (gdbarch)
- && name && strcmp (name, "main") == 0)
- {
- pc = gdbarch_skip_main_prologue (gdbarch, pc);
- /* Recalculate the line number (might not be N+1). */
+ /* If the function is in an unmapped overlay, use its unmapped LMA address,
+ so that gdbarch_skip_prologue has something unique to work on. */
+ if (section_is_overlay (section) && !section_is_mapped (section))
+ pc = overlay_unmapped_address (pc, section);
+
+ /* Skip "first line" of function (which is actually its prologue). */
+ pc += gdbarch_deprecated_function_start_offset (gdbarch);
+ if (skip)
+ pc = gdbarch_skip_prologue (gdbarch, pc);
+
+ /* For overlays, map pc back into its mapped VMA range. */
+ pc = overlay_mapped_address (pc, section);
+
+ /* Calculate line number. */
start_sal = find_pc_sect_line (pc, section, 0);
+
+ /* Check if gdbarch_skip_prologue left us in mid-line, and the next
+ line is still part of the same function. */
+ if (skip && start_sal.pc != pc
+ && (sym ? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end
+ && start_sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
+ : (lookup_minimal_symbol_by_pc_section (start_sal.end, section)
+ == lookup_minimal_symbol_by_pc_section (pc, section))))
+ {
+ /* First pc of next line */
+ pc = start_sal.end;
+ /* Recalculate the line number (might not be N+1). */
+ start_sal = find_pc_sect_line (pc, section, 0);
+ }
+
+ /* On targets with executable formats that don't have a concept of
+ constructors (ELF with .init has, PE doesn't), gcc emits a call
+ to `__main' in `main' between the prologue and before user
+ code. */
+ if (gdbarch_skip_main_prologue_p (gdbarch)
+ && name && strcmp (name, "main") == 0)
+ {
+ pc = gdbarch_skip_main_prologue (gdbarch, pc);
+ /* Recalculate the line number (might not be N+1). */
+ start_sal = find_pc_sect_line (pc, section, 0);
+ force_skip = 1;
+ }
}
+ while (!force_skip && skip--);
/* If we still don't have a valid source line, try to find the first
PC in the lineinfo table that belongs to the same function. This
the case with the DJGPP target using "gcc -gcoff" when the
compiler inserted code after the prologue to make sure the stack
is aligned. */
- if (sym && start_sal.symtab == NULL)
+ if (!force_skip && sym && start_sal.symtab == NULL)
{
pc = skip_prologue_using_lineinfo (pc, SYMBOL_SYMTAB (sym));
/* Recalculate the line number. */
some legitimate operator text, return a pointer to the
beginning of the substring of the operator text.
Otherwise, return "". */
-char *
+static char *
operator_chars (char *p, char **end)
{
*end = "";
/* A callback for map_partial_symbol_filenames. */
static void
-output_partial_symbol_filename (const char *fullname, const char *filename,
+output_partial_symbol_filename (const char *filename, const char *fullname,
void *data)
{
output_source_filename (fullname ? fullname : filename, data);
"will be read in on demand:\n\n");
first = 1;
- map_partial_symbol_filenames (output_partial_symbol_filename, &first);
+ map_partial_symbol_filenames (output_partial_symbol_filename, &first,
+ 1 /*need_fullname*/);
printf_filtered ("\n");
}
{
int nfiles;
char **files;
- char *regexp;
+
+ /* It is true if PREG contains valid data, false otherwise. */
+ unsigned preg_p : 1;
+ regex_t preg;
};
/* A callback for expand_symtabs_matching. */
/* A callback for expand_symtabs_matching. */
static int
-search_symbols_name_matches (const char *symname, void *user_data)
+search_symbols_name_matches (const struct language_defn *language,
+ const char *symname, void *user_data)
{
struct search_symbols_data *data = user_data;
- return data->regexp == NULL || re_exec (symname);
+ return !data->preg_p || regexec (&data->preg, symname, 0, NULL, 0) == 0;
}
/* Search the symbol table for matches to the regular expression REGEXP,
and constants (enums)
FUNCTIONS_DOMAIN - search all functions
TYPES_DOMAIN - search all type names
+ ALL_DOMAIN - an internal error for this function
free_search_symbols should be called when *MATCHES is no longer needed.
struct symbol_search *sr;
struct symbol_search *psr;
struct symbol_search *tail;
- struct cleanup *old_chain = NULL;
struct search_symbols_data datum;
+ /* OLD_CHAIN .. RETVAL_CHAIN is always freed, RETVAL_CHAIN .. current
+ CLEANUP_CHAIN is freed only in the case of an error. */
+ struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
+ struct cleanup *retval_chain;
+
gdb_assert (kind <= TYPES_DOMAIN);
ourtype = types[kind];
sr = *matches = NULL;
tail = NULL;
+ datum.preg_p = 0;
if (regexp != NULL)
{
and <TYPENAME> or <OPERATOR>. */
char *opend;
char *opname = operator_chars (regexp, &opend);
+ int errcode;
if (*opname)
{
}
}
- if (0 != (val = re_comp (regexp)))
- error (_("Invalid regexp (%s): %s"), val, regexp);
+ errcode = regcomp (&datum.preg, regexp,
+ REG_NOSUB | (case_sensitivity == case_sensitive_off
+ ? REG_ICASE : 0));
+ if (errcode != 0)
+ {
+ char *err = get_regcomp_error (errcode, &datum.preg);
+
+ make_cleanup (xfree, err);
+ error (_("Invalid regexp (%s): %s"), err, regexp);
+ }
+ datum.preg_p = 1;
+ make_regfree_cleanup (&datum.preg);
}
/* Search through the partial symtabs *first* for all symbols
datum.nfiles = nfiles;
datum.files = files;
- datum.regexp = regexp;
ALL_OBJFILES (objfile)
{
if (objfile->sf)
&datum);
}
+ retval_chain = old_chain;
+
/* Here, we search through the minimal symbol tables for functions
and variables that match, and force their symbols to be read.
This is in particular necessary for demangled variable names,
MSYMBOL_TYPE (msymbol) == ourtype3 ||
MSYMBOL_TYPE (msymbol) == ourtype4)
{
- if (regexp == NULL
- || re_exec (SYMBOL_NATURAL_NAME (msymbol)) != 0)
+ if (!datum.preg_p
+ || regexec (&datum.preg, SYMBOL_NATURAL_NAME (msymbol), 0,
+ NULL, 0) == 0)
{
if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)))
{
QUIT;
if (file_matches (real_symtab->filename, files, nfiles)
- && ((regexp == NULL
- || re_exec (SYMBOL_NATURAL_NAME (sym)) != 0)
+ && ((!datum.preg_p
+ || regexec (&datum.preg, SYMBOL_NATURAL_NAME (sym), 0,
+ NULL, 0) == 0)
&& ((kind == VARIABLES_DOMAIN
&& SYMBOL_CLASS (sym) != LOC_TYPEDEF
&& SYMBOL_CLASS (sym) != LOC_UNRESOLVED
tail = sort_search_symbols (&dummy, nfound);
sr = dummy.next;
- old_chain = make_cleanup_free_search_symbols (sr);
+ make_cleanup_free_search_symbols (sr);
}
else
tail = sort_search_symbols (prevtail, nfound);
MSYMBOL_TYPE (msymbol) == ourtype3 ||
MSYMBOL_TYPE (msymbol) == ourtype4)
{
- if (regexp == NULL
- || re_exec (SYMBOL_NATURAL_NAME (msymbol)) != 0)
+ if (!datum.preg_p
+ || regexec (&datum.preg, SYMBOL_NATURAL_NAME (msymbol), 0,
+ NULL, 0) == 0)
{
/* Functions: Look up by address. */
if (kind != FUNCTIONS_DOMAIN ||
if (tail == NULL)
{
sr = psr;
- old_chain = make_cleanup_free_search_symbols (sr);
+ make_cleanup_free_search_symbols (sr);
}
else
tail->next = psr;
}
}
+ discard_cleanups (retval_chain);
+ do_cleanups (old_chain);
*matches = sr;
- if (sr != NULL)
- discard_cleanups (old_chain);
}
/* Helper function for symtab_symbol_info, this function uses
}
\f
+/* Evaluate if NAME matches SYM_TEXT and SYM_TEXT_LEN.
+
+ Either sym_text[sym_text_len] != '(' and then we search for any
+ symbol starting with SYM_TEXT text.
+
+ Otherwise sym_text[sym_text_len] == '(' and then we require symbol name to
+ be terminated at that point. Partial symbol tables do not have parameters
+ information. */
+
+static int
+compare_symbol_name (const char *name, const char *sym_text, int sym_text_len)
+{
+ int (*ncmp) (const char *, const char *, size_t);
+
+ ncmp = (case_sensitivity == case_sensitive_on ? strncmp : strncasecmp);
+
+ if (ncmp (name, sym_text, sym_text_len) != 0)
+ return 0;
+
+ if (sym_text[sym_text_len] == '(')
+ {
+ /* User searches for `name(someth...'. Require NAME to be terminated.
+ Normally psymtabs and gdbindex have no parameter types so '\0' will be
+ present but accept even parameters presence. In this case this
+ function is in fact strcmp_iw but whitespace skipping is not supported
+ for tab completion. */
+
+ if (name[sym_text_len] != '\0' && name[sym_text_len] != '(')
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Free any memory associated with a completion list. */
+
+static void
+free_completion_list (char ***list_ptr)
+{
+ int i = 0;
+ char **list = *list_ptr;
+
+ while (list[i] != NULL)
+ {
+ xfree (list[i]);
+ i++;
+ }
+ xfree (list);
+}
+
+/* Callback for make_cleanup. */
+
+static void
+do_free_completion_list (void *list)
+{
+ free_completion_list (list);
+}
+
/* Helper routine for make_symbol_completion_list. */
static int return_val_size;
int newsize;
/* Clip symbols that cannot match. */
-
- if (strncmp (symname, sym_text, sym_text_len) != 0)
- {
- return;
- }
+ if (!compare_symbol_name (symname, sym_text, sym_text_len))
+ return;
/* We have a match for a completion, so add SYMNAME to the current list
of matches. Note that the name is moved to freshly malloc'd space. */
}
/* Type of the user_data argument passed to add_macro_name or
- add_partial_symbol_name. The contents are simply whatever is
+ expand_partial_symbol_name. The contents are simply whatever is
needed by completion_list_add_name. */
struct add_name_data
{
This adds a macro's name to the current completion list. */
static void
add_macro_name (const char *name, const struct macro_definition *ignore,
+ struct macro_source_file *ignore2, int ignore3,
void *user_data)
{
struct add_name_data *datum = (struct add_name_data *) user_data;
datum->text, datum->word);
}
-/* A callback for map_partial_symbol_names. */
-static void
-add_partial_symbol_name (const char *name, void *user_data)
+/* A callback for expand_partial_symbol_names. */
+static int
+expand_partial_symbol_name (const struct language_defn *language,
+ const char *name, void *user_data)
{
struct add_name_data *datum = (struct add_name_data *) user_data;
- completion_list_add_name ((char *) name,
- datum->sym_text, datum->sym_text_len,
- datum->text, datum->word);
+ return compare_symbol_name (name, datum->sym_text, datum->sym_text_len);
}
char **
/* Length of sym_text. */
int sym_text_len;
struct add_name_data datum;
+ struct cleanup *back_to;
/* Now look for the symbol we are supposed to complete on. */
{
sym_text_len = strlen (sym_text);
+ /* Prepare SYM_TEXT_LEN for compare_symbol_name. */
+
+ if (current_language->la_language == language_cplus
+ || current_language->la_language == language_java
+ || current_language->la_language == language_fortran)
+ {
+ /* These languages may have parameters entered by user but they are never
+ present in the partial symbol tables. */
+
+ const char *cs = memchr (sym_text, '(', sym_text_len);
+
+ if (cs)
+ sym_text_len = cs - sym_text;
+ }
+ gdb_assert (sym_text[sym_text_len] == '\0' || sym_text[sym_text_len] == '(');
+
return_val_size = 100;
return_val_index = 0;
return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *));
return_val[0] = NULL;
+ back_to = make_cleanup (do_free_completion_list, &return_val);
datum.sym_text = sym_text;
datum.sym_text_len = sym_text_len;
datum.word = word;
/* Look through the partial symtabs for all symbols which begin
- by matching SYM_TEXT. Add each one that you find to the list. */
- map_partial_symbol_names (add_partial_symbol_name, &datum);
+ by matching SYM_TEXT. Expand all CUs that you find to the list.
+ The real names will get added by COMPLETION_LIST_ADD_SYMBOL below. */
+ expand_partial_symbol_names (expand_partial_symbol_name, &datum);
/* At this point scan through the misc symbol vectors and add each
symbol you find to the list. Eventually we want to ignore
macro_for_each (macro_user_macros, add_macro_name, &datum);
}
+ discard_cleanups (back_to);
return (return_val);
}
char **list = (char **) xmalloc (list_alloced * sizeof (char *));
const char *base_name;
struct add_partial_filename_data datum;
+ struct cleanup *back_to;
list[0] = NULL;
if (!have_full_symbols () && !have_partial_symbols ())
return list;
+ back_to = make_cleanup (do_free_completion_list, &list);
+
ALL_SYMTABS (objfile, s)
{
if (not_interesting_fname (s->filename))
datum.list = &list;
datum.list_used = &list_used;
datum.list_alloced = &list_alloced;
- map_partial_symbol_filenames (maybe_add_partial_symtab_filename, &datum);
+ map_partial_symbol_filenames (maybe_add_partial_symtab_filename, &datum,
+ 0 /*need_fullname*/);
+ discard_cleanups (back_to);
return list;
}
The functions end point and an increasing SAL line are used as
indicators of the prologue's endpoint.
- This code is based on the function refine_prologue_limit (versions
- found in both ia64 and ppc). */
+ This code is based on the function refine_prologue_limit
+ (found in ia64). */
CORE_ADDR
skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
prologue_sal = find_pc_line (start_pc, 0);
if (prologue_sal.line != 0)
{
- /* For langauges other than assembly, treat two consecutive line
+ /* For languages other than assembly, treat two consecutive line
entries at the same address as a zero-instruction prologue.
The GNU assembler emits separate line notes for each instruction
in a multi-instruction macro, but compilers generally will not
}
\f
struct symtabs_and_lines
-decode_line_spec (char *string, int funfirstline)
+decode_line_spec (char *string, int flags)
{
struct symtabs_and_lines sals;
struct symtab_and_line cursal;
and get a default or it will recursively call us! */
cursal = get_current_source_symtab_and_line ();
- sals = decode_line_1 (&string, funfirstline,
- cursal.symtab, cursal.line,
- NULL);
+ sals = decode_line_1 (&string, flags,
+ cursal.symtab, cursal.line);
if (*string)
error (_("Junk at end of line specification: %s"), string);
set_main_name (NULL);
}
-/* Helper to expand_line_sal below. Appends new sal to SAL,
- initializing it from SYMTAB, LINENO and PC. */
-static void
-append_expanded_sal (struct symtabs_and_lines *sal,
- struct program_space *pspace,
- struct symtab *symtab,
- int lineno, CORE_ADDR pc)
-{
- sal->sals = xrealloc (sal->sals,
- sizeof (sal->sals[0])
- * (sal->nelts + 1));
- init_sal (sal->sals + sal->nelts);
- sal->sals[sal->nelts].pspace = pspace;
- sal->sals[sal->nelts].symtab = symtab;
- sal->sals[sal->nelts].section = NULL;
- sal->sals[sal->nelts].end = 0;
- sal->sals[sal->nelts].line = lineno;
- sal->sals[sal->nelts].pc = pc;
- ++sal->nelts;
-}
-
-/* Helper to expand_line_sal below. Search in the symtabs for any
- linetable entry that exactly matches FULLNAME and LINENO and append
- them to RET. If FULLNAME is NULL or if a symtab has no full name,
- use FILENAME and LINENO instead. If there is at least one match,
- return 1; otherwise, return 0, and return the best choice in BEST_ITEM
- and BEST_SYMTAB. */
-
-static int
-append_exact_match_to_sals (char *filename, char *fullname, int lineno,
- struct symtabs_and_lines *ret,
- struct linetable_entry **best_item,
- struct symtab **best_symtab)
-{
- struct program_space *pspace;
- struct objfile *objfile;
- struct symtab *symtab;
- int exact = 0;
- int j;
- *best_item = 0;
- *best_symtab = 0;
-
- ALL_PSPACES (pspace)
- ALL_PSPACE_SYMTABS (pspace, objfile, symtab)
- {
- if (FILENAME_CMP (filename, symtab->filename) == 0)
- {
- struct linetable *l;
- int len;
-
- if (fullname != NULL
- && symtab_to_fullname (symtab) != NULL
- && FILENAME_CMP (fullname, symtab->fullname) != 0)
- continue;
- l = LINETABLE (symtab);
- if (!l)
- continue;
- len = l->nitems;
-
- for (j = 0; j < len; j++)
- {
- struct linetable_entry *item = &(l->item[j]);
-
- if (item->line == lineno)
- {
- exact = 1;
- append_expanded_sal (ret, objfile->pspace,
- symtab, lineno, item->pc);
- }
- else if (!exact && item->line > lineno
- && (*best_item == NULL
- || item->line < (*best_item)->line))
- {
- *best_item = item;
- *best_symtab = symtab;
- }
- }
- }
- }
- return exact;
-}
-
-/* Compute a set of all sals in all program spaces that correspond to
- same file and line as SAL and return those. If there are several
- sals that belong to the same block, only one sal for the block is
- included in results. */
-
-struct symtabs_and_lines
-expand_line_sal (struct symtab_and_line sal)
-{
- struct symtabs_and_lines ret;
- int i, j;
- struct objfile *objfile;
- int lineno;
- int deleted = 0;
- struct block **blocks = NULL;
- int *filter;
- struct cleanup *old_chain;
-
- ret.nelts = 0;
- ret.sals = NULL;
-
- /* Only expand sals that represent file.c:line. */
- if (sal.symtab == NULL || sal.line == 0 || sal.pc != 0)
- {
- ret.sals = xmalloc (sizeof (struct symtab_and_line));
- ret.sals[0] = sal;
- ret.nelts = 1;
- return ret;
- }
- else
- {
- struct program_space *pspace;
- struct linetable_entry *best_item = 0;
- struct symtab *best_symtab = 0;
- int exact = 0;
- char *match_filename;
-
- lineno = sal.line;
- match_filename = sal.symtab->filename;
-
- /* We need to find all symtabs for a file which name
- is described by sal. We cannot just directly
- iterate over symtabs, since a symtab might not be
- yet created. We also cannot iterate over psymtabs,
- calling PSYMTAB_TO_SYMTAB and working on that symtab,
- since PSYMTAB_TO_SYMTAB will return NULL for psymtab
- corresponding to an included file. Therefore, we do
- first pass over psymtabs, reading in those with
- the right name. Then, we iterate over symtabs, knowing
- that all symtabs we're interested in are loaded. */
-
- old_chain = save_current_program_space ();
- ALL_PSPACES (pspace)
- {
- set_current_program_space (pspace);
- ALL_PSPACE_OBJFILES (pspace, objfile)
- {
- if (objfile->sf)
- objfile->sf->qf->expand_symtabs_with_filename (objfile,
- sal.symtab->filename);
- }
- }
- do_cleanups (old_chain);
-
- /* Now search the symtab for exact matches and append them. If
- none is found, append the best_item and all its exact
- matches. */
- symtab_to_fullname (sal.symtab);
- exact = append_exact_match_to_sals (sal.symtab->filename,
- sal.symtab->fullname, lineno,
- &ret, &best_item, &best_symtab);
- if (!exact && best_item)
- append_exact_match_to_sals (best_symtab->filename,
- best_symtab->fullname, best_item->line,
- &ret, &best_item, &best_symtab);
- }
-
- /* For optimized code, compiler can scatter one source line accross
- disjoint ranges of PC values, even when no duplicate functions
- or inline functions are involved. For example, 'for (;;)' inside
- non-template non-inline non-ctor-or-dtor function can result
- in two PC ranges. In this case, we don't want to set breakpoint
- on first PC of each range. To filter such cases, we use containing
- blocks -- for each PC found above we see if there are other PCs
- that are in the same block. If yes, the other PCs are filtered out. */
-
- old_chain = save_current_program_space ();
- filter = alloca (ret.nelts * sizeof (int));
- blocks = alloca (ret.nelts * sizeof (struct block *));
- for (i = 0; i < ret.nelts; ++i)
- {
- set_current_program_space (ret.sals[i].pspace);
-
- filter[i] = 1;
- blocks[i] = block_for_pc_sect (ret.sals[i].pc, ret.sals[i].section);
-
- }
- do_cleanups (old_chain);
-
- for (i = 0; i < ret.nelts; ++i)
- if (blocks[i] != NULL)
- for (j = i+1; j < ret.nelts; ++j)
- if (blocks[j] == blocks[i])
- {
- filter[j] = 0;
- ++deleted;
- break;
- }
-
- {
- struct symtab_and_line *final =
- xmalloc (sizeof (struct symtab_and_line) * (ret.nelts-deleted));
-
- for (i = 0, j = 0; i < ret.nelts; ++i)
- if (filter[i])
- final[j++] = ret.sals[i];
-
- ret.nelts -= deleted;
- xfree (ret.sals);
- ret.sals = final;
- }
-
- return ret;
-}
-
/* Return 1 if the supplied producer string matches the ARM RealView
compiler (armcc). */
Valid values are \"ask\", \"all\", \"cancel\", and the default is \"all\"."),
NULL, NULL, &setlist, &showlist);
+ add_setshow_boolean_cmd ("basenames-may-differ", class_obscure,
+ &basenames_may_differ, _("\
+Set whether a source file may have multiple base names."), _("\
+Show whether a source file may have multiple base names."), _("\
+(A \"base name\" is the name of a file with the directory part removed.\n\
+Example: The base name of \"/home/user/hello.c\" is \"hello.c\".)\n\
+If set, GDB will canonicalize file names (e.g., expand symlinks)\n\
+before comparing them. Canonicalization is an expensive operation,\n\
+but it allows the same file be known by more than one base name.\n\
+If not set (the default), all source files are assumed to have just\n\
+one base name, and gdb will do file name comparisons more efficiently."),
+ NULL, NULL,
+ &setlist, &showlist);
+
observer_attach_executable_changed (symtab_observer_executable_changed);
}