This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: creating the gdb-7.4 branch tomorrow (?)
- From: Tom Tromey <tromey at redhat dot com>
- To: Joel Brobecker <brobecker at adacore dot com>
- Cc: gdb-patches at sourceware dot org
- Date: Tue, 06 Dec 2011 11:39:47 -0700
- Subject: Re: creating the gdb-7.4 branch tomorrow (?)
- References: <20111205081911.GG28486@adacore.com>
Finally, patch #5. This is another Ada patch, from Joel.
Tom
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 250aba2..3843539 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -5052,29 +5052,43 @@ done:
return ndefns;
}
-/* Implementation of the la_iterate_over_symbols method. */
+/* If NAME is the name of an entity, return a string that should
+ be used to look that entity up in Ada units. This string should
+ be deallocated after use using xfree.
-static void
-ada_iterate_over_symbols (const struct block *block,
- const char *name, domain_enum domain,
- int (*callback) (struct symbol *, void *),
- void *data)
+ NAME can have any form that the "break" or "print" commands might
+ recognize. In other words, it does not have to be the "natural"
+ name, or the "encoded" name. */
+
+char *
+ada_name_for_lookup (const char *name)
{
- int ndefs, i;
- struct ada_symbol_info *results;
char *canon;
int nlen = strlen (name);
if (name[0] == '<' && name[nlen - 1] == '>')
{
- canon = alloca (nlen - 1);
+ canon = xmalloc (nlen - 1);
memcpy (canon, name + 1, nlen - 2);
canon[nlen - 2] = '\0';
}
else
- canon = ada_encode (ada_fold_name (name));
+ canon = xstrdup (ada_encode (ada_fold_name (name)));
+ return canon;
+}
+
+/* Implementation of the la_iterate_over_symbols method. */
+
+static void
+ada_iterate_over_symbols (const struct block *block,
+ const char *name, domain_enum domain,
+ int (*callback) (struct symbol *, void *),
+ void *data)
+{
+ int ndefs, i;
+ struct ada_symbol_info *results;
- ndefs = ada_lookup_symbol_list (canon, block, domain, &results);
+ ndefs = ada_lookup_symbol_list (name, block, domain, &results);
for (i = 0; i < ndefs; ++i)
{
if (! (*callback) (results[i].sym, data))
@@ -5663,7 +5677,8 @@ struct add_partial_datum
/* A callback for expand_partial_symbol_names. */
static int
-ada_expand_partial_symbol_name (const char *name, void *user_data)
+ada_expand_partial_symbol_name (const struct language_defn *language,
+ const char *name, void *user_data)
{
struct add_partial_datum *data = user_data;
@@ -12312,6 +12327,7 @@ const struct language_defn ada_language_defn = {
ada_print_array_index,
default_pass_by_reference,
c_get_string,
+ compare_names,
ada_iterate_over_symbols,
LANG_MAGIC
};
diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h
index d6404ca..fa4bb51 100644
--- a/gdb/ada-lang.h
+++ b/gdb/ada-lang.h
@@ -365,6 +365,8 @@ extern char *ada_breakpoint_rewrite (char *, int *);
extern char *ada_main_name (void);
+extern char *ada_name_for_lookup (const char *name);
+
/* Tasking-related: ada-tasks.c */
extern int valid_task_id (int);
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index 81e7849..7be916c 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -863,6 +863,7 @@ const struct language_defn c_language_defn =
default_print_array_index,
default_pass_by_reference,
c_get_string,
+ strcmp_iw_ordered,
iterate_over_symbols,
LANG_MAGIC
};
@@ -985,6 +986,7 @@ const struct language_defn cplus_language_defn =
default_print_array_index,
cp_pass_by_reference,
c_get_string,
+ strcmp_iw_ordered,
iterate_over_symbols,
LANG_MAGIC
};
@@ -1025,6 +1027,7 @@ const struct language_defn asm_language_defn =
default_print_array_index,
default_pass_by_reference,
c_get_string,
+ strcmp_iw_ordered,
iterate_over_symbols,
LANG_MAGIC
};
@@ -1070,6 +1073,7 @@ const struct language_defn minimal_language_defn =
default_print_array_index,
default_pass_by_reference,
c_get_string,
+ strcmp_iw_ordered,
iterate_over_symbols,
LANG_MAGIC
};
diff --git a/gdb/d-lang.c b/gdb/d-lang.c
index 44ff68a..fb6bacd 100644
--- a/gdb/d-lang.c
+++ b/gdb/d-lang.c
@@ -273,6 +273,7 @@ static const struct language_defn d_language_defn =
default_print_array_index,
default_pass_by_reference,
c_get_string,
+ strcmp_iw_ordered,
NULL,
LANG_MAGIC
};
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 49a7a17..74d4357 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -2756,11 +2756,12 @@ dw2_map_matching_symbols (const char * name, domain_enum namespace,
}
static void
-dw2_expand_symtabs_matching (struct objfile *objfile,
- int (*file_matcher) (const char *, void *),
- int (*name_matcher) (const char *, void *),
- enum search_domain kind,
- void *data)
+dw2_expand_symtabs_matching
+ (struct objfile *objfile,
+ int (*file_matcher) (const char *, void *),
+ int (*name_matcher) (const struct language_defn *, const char *, void *),
+ enum search_domain kind,
+ void *data)
{
int i;
offset_type iter;
@@ -2812,7 +2813,7 @@ dw2_expand_symtabs_matching (struct objfile *objfile,
name = index->constant_pool + MAYBE_SWAP (index->symbol_table[idx]);
- if (! (*name_matcher) (name, data))
+ if (! (*name_matcher) (current_language, name, data))
continue;
/* The name was matched, now expand corresponding CUs that were
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 7a8516d..00926fb 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -309,6 +309,7 @@ const struct language_defn f_language_defn =
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ strcmp_iw_ordered,
iterate_over_symbols,
LANG_MAGIC
};
diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c
index ce65a2d..80fe4a1 100644
--- a/gdb/jv-lang.c
+++ b/gdb/jv-lang.c
@@ -1197,6 +1197,7 @@ const struct language_defn java_language_defn =
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ strcmp_iw_ordered,
iterate_over_symbols,
LANG_MAGIC
};
diff --git a/gdb/language.c b/gdb/language.c
index 701c479..1bbbfba 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -1200,6 +1200,7 @@ const struct language_defn unknown_language_defn =
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ strcmp_iw_ordered,
iterate_over_symbols,
LANG_MAGIC
};
@@ -1242,6 +1243,7 @@ const struct language_defn auto_language_defn =
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ strcmp_iw_ordered,
iterate_over_symbols,
LANG_MAGIC
};
@@ -1282,6 +1284,7 @@ const struct language_defn local_language_defn =
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ strcmp_iw_ordered,
iterate_over_symbols,
LANG_MAGIC
};
diff --git a/gdb/language.h b/gdb/language.h
index 82e6a88..65d55db 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -318,6 +318,20 @@ struct language_defn
void (*la_get_string) (struct value *value, gdb_byte **buffer, int *length,
struct type **chartype, const char **charset);
+ /* Compare two symbol names according to language rules. For
+ instance, in C++, we might want to ignore whitespaces in
+ the symbol name. Or some case-insensitive language might
+ want to ignore casing during the match.
+
+ Both STR1 and STR2 are expected to be demangled name, except
+ for Ada, where STR1 and STR2 are expected to be encoded names.
+ The latter is because searches are performed using the encoded
+ name in Ada.
+
+ The return value follows the same spirit as strcmp. */
+
+ int (*la_symbol_name_compare) (const char *str1, const char *str2);
+
/* Find all symbols in the current program space matching NAME in
DOMAIN, according to this language's rules.
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 8b357a3..e6e863d 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -44,6 +44,7 @@
#include <ctype.h>
#include "cli/cli-utils.h"
#include "filenames.h"
+#include "ada-lang.h"
typedef struct symtab *symtab_p;
DEF_VEC_P (symtab_p);
@@ -327,11 +328,12 @@ cplusplus_error (const char *name, const char *fmt, ...)
callback to the expand_symtabs_matching method. */
static int
-iterate_name_matcher (const char *name, void *d)
+iterate_name_matcher (const struct language_defn *language,
+ const char *name, void *d)
{
const char **dname = d;
- if (strcmp_iw (name, *dname) == 0)
+ if (language->la_symbol_name_compare (name, *dname) == 0)
return 1;
return 0;
}
@@ -2811,6 +2813,13 @@ decode_variable (struct linespec_state *self, char *copy)
cleanup = demangle_for_lookup (copy, current_language->la_language,
&lookup_name);
+ if (current_language->la_language == language_ada)
+ {
+ /* In Ada, the symbol lookups are performed using the encoded
+ name rather than the demangled name. */
+ lookup_name = ada_name_for_lookup (copy);
+ make_cleanup (xfree, (void *) lookup_name);
+ }
canon = cp_canonicalize_string_no_typedefs (lookup_name);
if (canon != NULL)
diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
index 106dfcf..c850b1f 100644
--- a/gdb/m2-lang.c
+++ b/gdb/m2-lang.c
@@ -401,6 +401,7 @@ const struct language_defn m2_language_defn =
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ strcmp_iw_ordered,
iterate_over_symbols,
LANG_MAGIC
};
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index 1da92a5..cb7fa0e 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -541,6 +541,7 @@ const struct language_defn objc_language_defn = {
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ strcmp_iw_ordered,
iterate_over_symbols,
LANG_MAGIC
};
diff --git a/gdb/opencl-lang.c b/gdb/opencl-lang.c
index 895a51c..1deb9d8 100644
--- a/gdb/opencl-lang.c
+++ b/gdb/opencl-lang.c
@@ -1024,6 +1024,7 @@ const struct language_defn opencl_language_defn =
default_print_array_index,
default_pass_by_reference,
c_get_string,
+ strcmp_iw_ordered,
iterate_over_symbols,
LANG_MAGIC
};
diff --git a/gdb/p-lang.c b/gdb/p-lang.c
index 30b890f..f66d471 100644
--- a/gdb/p-lang.c
+++ b/gdb/p-lang.c
@@ -459,6 +459,7 @@ const struct language_defn pascal_language_defn =
default_print_array_index,
default_pass_by_reference,
default_get_string,
+ strcmp_iw_ordered,
iterate_over_symbols,
LANG_MAGIC
};
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 871650f..74185cc 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -1249,13 +1249,12 @@ map_matching_symbols_psymtab (const char *name, domain_enum namespace,
}
static void
-expand_symtabs_matching_via_partial (struct objfile *objfile,
- int (*file_matcher) (const char *,
- void *),
- int (*name_matcher) (const char *,
- void *),
- enum search_domain kind,
- void *data)
+expand_symtabs_matching_via_partial
+ (struct objfile *objfile,
+ int (*file_matcher) (const char *, void *),
+ int (*name_matcher) (const struct language_defn *, const char *, void *),
+ enum search_domain kind,
+ void *data)
{
struct partial_symtab *ps;
@@ -1305,7 +1304,8 @@ expand_symtabs_matching_via_partial (struct objfile *objfile,
&& SYMBOL_CLASS (*psym) == LOC_BLOCK)
|| (kind == TYPES_DOMAIN
&& SYMBOL_CLASS (*psym) == LOC_TYPEDEF))
- && (*name_matcher) (SYMBOL_NATURAL_NAME (*psym), data))
+ && (*name_matcher) (current_language,
+ SYMBOL_NATURAL_NAME (*psym), data))
{
PSYMTAB_TO_SYMTAB (ps);
keep_going = 0;
@@ -1945,7 +1945,9 @@ maintenance_check_symtabs (char *ignore, int from_tty)
void
-expand_partial_symbol_names (int (*fun) (const char *, void *), void *data)
+expand_partial_symbol_names (int (*fun) (const struct language_defn *,
+ const char *, void *),
+ void *data)
{
struct objfile *objfile;
diff --git a/gdb/psymtab.h b/gdb/psymtab.h
index de292c5..940b537 100644
--- a/gdb/psymtab.h
+++ b/gdb/psymtab.h
@@ -30,7 +30,8 @@ extern struct psymbol_bcache *psymbol_bcache_init (void);
extern void psymbol_bcache_free (struct psymbol_bcache *);
extern struct bcache *psymbol_bcache_get_bcache (struct psymbol_bcache *);
-void expand_partial_symbol_names (int (*fun) (const char *, void *),
+void expand_partial_symbol_names (int (*fun) (const struct language_defn *,
+ const char *, void *),
void *data);
void map_partial_symbol_filenames (symbol_filename_ftype *fun, void *data,
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 8b3b705..44f0c01 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -261,9 +261,12 @@ struct quick_symbol_functions
Otherwise, if KIND does not match this symbol is skipped.
- If even KIND matches, then NAME_MATCHER is called for each symbol defined
- in the file. The symbol's "natural" name and DATA are passed to
- NAME_MATCHER.
+ If even KIND matches, then NAME_MATCHER is called for each symbol
+ defined in the file. The current language, the symbol name and
+ DATA are passed to NAME_MATCHER. The symbol "natural" name should
+ be passed to NAME_MATCHER for all languages except Ada, where
+ the encoded name is passed instead (see la_symbol_name_compare in
+ struct language_defn for more details on this).
If NAME_MATCHER returns zero, then this symbol is skipped.
@@ -271,11 +274,12 @@ struct quick_symbol_functions
DATA is user data that is passed unmodified to the callback
functions. */
- void (*expand_symtabs_matching) (struct objfile *objfile,
- int (*file_matcher) (const char *, void *),
- int (*name_matcher) (const char *, void *),
- enum search_domain kind,
- void *data);
+ void (*expand_symtabs_matching)
+ (struct objfile *objfile,
+ int (*file_matcher) (const char *, void *),
+ int (*name_matcher) (const struct language_defn *, const char *, void *),
+ enum search_domain kind,
+ void *data);
/* Return the symbol table from OBJFILE that contains PC and
SECTION. Return NULL if there is no such symbol table. This
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 3ae5cf9..1ea4253 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1054,7 +1054,21 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
/* 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. */
+ 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. */
struct cleanup *
demangle_for_lookup (const char *name, enum language lang,
@@ -3152,7 +3166,8 @@ search_symbols_file_matches (const char *filename, void *user_data)
/* 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;
@@ -3960,7 +3975,8 @@ add_macro_name (const char *name, const struct macro_definition *ignore,
/* A callback for expand_partial_symbol_names. */
static int
-expand_partial_symbol_name (const char *name, void *user_data)
+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;
diff --git a/gdb/testsuite/gdb.ada/fullname_bp.exp b/gdb/testsuite/gdb.ada/fullname_bp.exp
index faf63b9..0e4d32f 100644
--- a/gdb/testsuite/gdb.ada/fullname_bp.exp
+++ b/gdb/testsuite/gdb.ada/fullname_bp.exp
@@ -25,6 +25,9 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug ]] != "" }
return -1
}
+# Note: We restart the debugger before setting each breakpoint, because
+# we want to test the situation where the symtab for our breakpoint
+# has not been created yet.
clean_restart ${testfile}
# Break on "pck.hello" rather than just "hello" to make sure we trigger
@@ -32,3 +35,23 @@ clean_restart ${testfile}
gdb_test "break pck.hello" \
"Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*pck.adb, line \[0-9\]+."
+# Do the same, but this time using a linespec where the user also
+# provided a filename.
+
+clean_restart ${testfile}
+
+gdb_test "break pck.adb:pck.hello" \
+ "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*pck.adb, line \[0-9\]+."
+
+# Same scenarios as above, but with a function name that is spelled
+# with upper-case letters.
+
+clean_restart ${testfile}
+
+gdb_test "break Pck.Hello" \
+ "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*pck.adb, line \[0-9\]+."
+
+clean_restart ${testfile}
+
+gdb_test "break pck.adb:Pck.Hello" \
+ "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*pck.adb, line \[0-9\]+."
--
1.7.6.4