static int find_line_common (struct linetable *, int, int *);
-/* This one is used by linespec.c */
-
-char *operator_chars (char *p, char **end);
-
static struct symbol *lookup_symbol_aux (const char *name,
const struct block *block,
const domain_enum domain,
const char *name,
const domain_enum domain);
-static void print_symbol_info (domain_enum,
- struct symtab *, struct symbol *, int, char *);
-
static void print_msymbol_info (struct minimal_symbol *);
-static void symtab_symbol_info (char *, domain_enum, int);
-
void _initialize_symtab (void);
/* */
+/* 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. */
struct objfile *objfile;
char *real_path = NULL;
char *full_path = NULL;
+ struct cleanup *cleanup;
+ const char* base_name = lbasename (name);
+
+ cleanup = make_cleanup (null_cleanup, NULL);
/* Here we are interested in canonicalizing an absolute path, not
absolutizing a relative path. */
{
if (FILENAME_CMP (name, s->filename) == 0)
{
+ do_cleanups (cleanup);
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)
{
+ do_cleanups (cleanup);
return s;
}
}
make_cleanup (xfree, rp);
if (FILENAME_CMP (real_path, rp) == 0)
{
+ do_cleanups (cleanup);
return s;
}
}
ALL_SYMTABS (objfile, s)
{
if (FILENAME_CMP (lbasename (s->filename), name) == 0)
- return s;
+ {
+ do_cleanups (cleanup);
+ return s;
+ }
}
/* Same search rules as above apply here, but now we look thru the
}
if (s != NULL)
- return s;
+ {
+ do_cleanups (cleanup);
+ return s;
+ }
if (!found)
- return NULL;
+ {
+ do_cleanups (cleanup);
+ return NULL;
+ }
/* At this point, we have located the psymtab for this file, but
the conversion to a symtab has failed. This usually happens
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
+ XXX - This is a crock, and should be fixed inside of the
symbol parsing routines. */
goto got_symtab;
}
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;
}
}
- 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;
- }
-
returnval = lookup_symbol_aux (modified_name, block, domain, lang,
is_a_field_of_this);
do_cleanups (cleanup);
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;
-
- /* '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));
+ struct symbol *sym = lookup_language_this (langdef, 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;
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 = "";
/* Is FILE in tab? */
for (p = tab; p < tab + tab_cur_size; p++)
- if (strcmp (*p, file) == 0)
+ if (filename_cmp (*p, file) == 0)
return 1;
/* No; maybe add it to tab. */
/* 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");
}
{
for (i = 0; i < nfiles; i++)
{
- if (strcmp (files[i], lbasename (file)) == 0)
+ if (filename_cmp (files[i], lbasename (file)) == 0)
return 1;
}
}
{
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. */
{
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,
returning the results in *MATCHES.
Only symbols of KIND are searched:
+ VARIABLES_DOMAIN - search all symbols, excluding functions, type names,
+ and constants (enums)
FUNCTIONS_DOMAIN - search all functions
TYPES_DOMAIN - search all type names
- VARIABLES_DOMAIN - search all symbols, excluding functions, type names,
- and constants (enums)
+ ALL_DOMAIN - an internal error for this function
free_search_symbols should be called when *MATCHES is no longer needed.
separately alphabetized. */
void
-search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
+search_symbols (char *regexp, enum search_domain kind,
+ int nfiles, char *files[],
struct symbol_search **matches)
{
struct symtab *s;
char *val;
int found_misc = 0;
static const enum minimal_symbol_type types[]
- = {mst_data, mst_text, mst_abs, mst_unknown};
+ = {mst_data, mst_text, mst_abs};
static const enum minimal_symbol_type types2[]
- = {mst_bss, mst_file_text, mst_abs, mst_unknown};
+ = {mst_bss, mst_file_text, mst_abs};
static const enum minimal_symbol_type types3[]
- = {mst_file_data, mst_solib_trampoline, mst_abs, mst_unknown};
+ = {mst_file_data, mst_solib_trampoline, mst_abs};
static const enum minimal_symbol_type types4[]
- = {mst_file_bss, mst_text, mst_abs, mst_unknown};
+ = {mst_file_bss, mst_text_gnu_ifunc, mst_abs};
enum minimal_symbol_type ourtype;
enum minimal_symbol_type ourtype2;
enum minimal_symbol_type ourtype3;
struct symbol_search *sr;
struct symbol_search *psr;
struct symbol_search *tail;
- struct cleanup *old_chain = NULL;
struct search_symbols_data datum;
- if (kind < VARIABLES_DOMAIN)
- error (_("must search on specific domain"));
+ /* 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[(int) (kind - VARIABLES_DOMAIN)];
- ourtype2 = types2[(int) (kind - VARIABLES_DOMAIN)];
- ourtype3 = types3[(int) (kind - VARIABLES_DOMAIN)];
- ourtype4 = types4[(int) (kind - VARIABLES_DOMAIN)];
+ ourtype = types[kind];
+ ourtype2 = types2[kind];
+ ourtype3 = types3[kind];
+ ourtype4 = types4[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
regarding the match to gdb_stdout. */
static void
-print_symbol_info (domain_enum kind, struct symtab *s, struct symbol *sym,
+print_symbol_info (enum search_domain kind,
+ struct symtab *s, struct symbol *sym,
int block, char *last)
{
- if (last == NULL || strcmp (last, s->filename) != 0)
+ if (last == NULL || filename_cmp (last, s->filename) != 0)
{
fputs_filtered ("\nFile ", gdb_stdout);
fputs_filtered (s->filename, gdb_stdout);
matches. */
static void
-symtab_symbol_info (char *regexp, domain_enum kind, int from_tty)
+symtab_symbol_info (char *regexp, enum search_domain kind, int from_tty)
{
static const char * const classnames[] =
- {"variable", "function", "type", "method"};
+ {"variable", "function", "type"};
struct symbol_search *symbols;
struct symbol_search *p;
struct cleanup *old_chain;
char *last_filename = NULL;
int first = 1;
+ gdb_assert (kind <= TYPES_DOMAIN);
+
/* Must make sure that if we're interrupted, symbols gets freed. */
search_symbols (regexp, kind, 0, (char **) NULL, &symbols);
old_chain = make_cleanup_free_search_symbols (symbols);
printf_filtered (regexp
? "All %ss matching regular expression \"%s\":\n"
: "All defined %ss:\n",
- classnames[(int) (kind - VARIABLES_DOMAIN)], regexp);
+ classnames[kind], regexp);
for (p = symbols; p != NULL; p = p->next)
{
struct cleanup *old_chain;
char *string = NULL;
int len = 0;
- char **files = NULL;
+ char **files = NULL, *file_name;
int nfiles = 0;
if (regexp)
if (colon && *(colon + 1) != ':')
{
int colon_index;
- char * file_name;
colon_index = colon - regexp;
file_name = alloca (colon_index + 1);
}
\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 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);
}
for (i = 0; illegal_aliens[i]; i++)
{
- if (strcmp (fname, illegal_aliens[i]) == 0)
+ if (filename_cmp (fname, illegal_aliens[i]) == 0)
return 1;
}
return 0;
if (not_interesting_fname (filename))
return;
if (!filename_seen (filename, 1, data->first)
-#if HAVE_DOS_BASED_FILE_SYSTEM
- && strncasecmp (filename, data->text, data->text_len) == 0
-#else
- && strncmp (filename, data->text, data->text_len) == 0
-#endif
- )
+ && filename_ncmp (filename, data->text, data->text_len) == 0)
{
/* This file matches for a completion; add it to the
current list of matches. */
if (base_name != filename
&& !filename_seen (base_name, 1, data->first)
-#if HAVE_DOS_BASED_FILE_SYSTEM
- && strncasecmp (base_name, data->text, data->text_len) == 0
-#else
- && strncmp (base_name, data->text, data->text_len) == 0
-#endif
- )
+ && filename_ncmp (base_name, data->text, data->text_len) == 0)
add_filename_to_list (base_name, data->text, data->word,
data->list, data->list_used, data->list_alloced);
}
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))
continue;
if (!filename_seen (s->filename, 1, &first)
-#if HAVE_DOS_BASED_FILE_SYSTEM
- && strncasecmp (s->filename, text, text_len) == 0
-#else
- && strncmp (s->filename, text, text_len) == 0
-#endif
- )
+ && filename_ncmp (s->filename, text, text_len) == 0)
{
/* This file matches for a completion; add it to the current
list of matches. */
base_name = lbasename (s->filename);
if (base_name != s->filename
&& !filename_seen (base_name, 1, &first)
-#if HAVE_DOS_BASED_FILE_SYSTEM
- && strncasecmp (base_name, text, text_len) == 0
-#else
- && strncmp (base_name, text, text_len) == 0
-#endif
- )
+ && filename_ncmp (base_name, text, text_len) == 0)
add_filename_to_list (base_name, text, word,
&list, &list_used, &list_alloced);
}
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
sals = decode_line_1 (&string, funfirstline,
cursal.symtab, cursal.line,
- (char ***) NULL, NULL);
+ NULL);
if (*string)
error (_("Junk at end of line specification: %s"), string);
filter[i] = 1;
blocks[i] = block_for_pc_sect (ret.sals[i].pc, ret.sals[i].section);
-
}
do_cleanups (old_chain);
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);
}