diff options
-rw-r--r-- | gdb/ChangeLog | 32 | ||||
-rw-r--r-- | gdb/ada-lang.c | 40 | ||||
-rw-r--r-- | gdb/c-lang.c | 4 | ||||
-rw-r--r-- | gdb/cp-support.c | 9 | ||||
-rw-r--r-- | gdb/cp-support.h | 4 | ||||
-rw-r--r-- | gdb/d-lang.c | 10 | ||||
-rw-r--r-- | gdb/defs.h | 18 | ||||
-rw-r--r-- | gdb/f-lang.c | 7 | ||||
-rw-r--r-- | gdb/go-lang.c | 10 | ||||
-rw-r--r-- | gdb/jv-lang.c | 10 | ||||
-rw-r--r-- | gdb/language.c | 20 | ||||
-rw-r--r-- | gdb/language.h | 23 | ||||
-rw-r--r-- | gdb/m2-lang.c | 1 | ||||
-rw-r--r-- | gdb/objc-lang.c | 10 | ||||
-rw-r--r-- | gdb/opencl-lang.c | 1 | ||||
-rw-r--r-- | gdb/p-lang.c | 1 | ||||
-rw-r--r-- | gdb/rust-lang.c | 13 | ||||
-rw-r--r-- | gdb/symtab.c | 107 |
18 files changed, 223 insertions, 97 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2224109..630dbc9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,37 @@ 2016-06-23 Tom Tromey <tom@tromey.com> + * symtab.c (symbol_find_demangled_name): Loop over languages and + use language_sniff_from_mangled_name. + * rust-lang.c (rust_sniff_from_mangled_name): New function. + (rust_language_defn): Update. + * p-lang.c (pascal_language_defn): Update. + * opencl-lang.c (opencl_language_defn): Update. + * objc-lang.c (objc_sniff_from_mangled_name): New function. + (objc_language_defn): Update. + * m2-lang.c (m2_language_defn): Update. + * language.h (struct language_defn) <la_sniff_from_mangled_name>: New + field. + (language_sniff_from_mangled_name): Declare. + * language.c (language_sniff_from_mangled_name): New function. + (unknown_language_defn, auto_language_defn, local_language_defn): + Update. + * jv-lang.c (java_sniff_from_mangled_name): New function. + (java_language_defn): Use it. + * go-lang.c (go_sniff_from_mangled_name): New function. + (go_language_defn): Use it. + * f-lang.c (f_language_defn): Update. + * defs.h (enum language): Reorder. + * d-lang.c (d_sniff_from_mangled_name): New function. + (d_language_defn): Use it. + * cp-support.h (gdb_sniff_from_mangled_name): Declare. + * cp-support.c (gdb_sniff_from_mangled_name): New function. + * c-lang.c (c_language_defn, cplus_language_defn) + (asm_language_defn, minimal_language_defn): Update. + * ada-lang.c (ada_sniff_from_mangled_name): New function. + (ada_language_defn): Use it. + +2016-06-23 Tom Tromey <tom@tromey.com> + * ada-lang.c (ada_extensions): New array. (ada_language_defn): Use it. * c-lang.c (c_extensions): New array. diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 796dc65..b22b7ac 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -1452,6 +1452,45 @@ ada_la_decode (const char *encoded, int options) return xstrdup (ada_decode (encoded)); } +/* Implement la_sniff_from_mangled_name for Ada. */ + +static int +ada_sniff_from_mangled_name (const char *mangled, char **out) +{ + const char *demangled = ada_decode (mangled); + + *out = NULL; + + if (demangled != mangled && demangled != NULL && demangled[0] != '<') + { + /* Set the gsymbol language to Ada, but still return 0. + Two reasons for that: + + 1. For Ada, we prefer computing the symbol's decoded name + on the fly rather than pre-compute it, in order to save + memory (Ada projects are typically very large). + + 2. There are some areas in the definition of the GNAT + encoding where, with a bit of bad luck, we might be able + to decode a non-Ada symbol, generating an incorrect + demangled name (Eg: names ending with "TB" for instance + are identified as task bodies and so stripped from + the decoded name returned). + + Returning 1, here, but not setting *DEMANGLED, helps us get a + little bit of the best of both worlds. Because we're last, + we should not affect any of the other languages that were + able to demangle the symbol before us; we get to correctly + tag Ada symbols as such; and even if we incorrectly tagged a + non-Ada symbol, which should be rare, any routing through the + Ada language should be transparent (Ada tries to behave much + like C/C++ with non-Ada symbols). */ + return 1; + } + + return 0; +} + /* Returns non-zero iff SYM_NAME matches NAME, ignoring any trailing suffixes that encode debugging information or leading _ada_ on SYM_NAME (see is_name_suffix commentary for the debugging @@ -14086,6 +14125,7 @@ const struct language_defn ada_language_defn = { ada_lookup_symbol_nonlocal, /* Looking up non-local symbols. */ basic_lookup_transparent_type, /* lookup_transparent_type */ ada_la_decode, /* Language specific symbol demangler */ + ada_sniff_from_mangled_name, NULL, /* Language specific class_name_from_physname */ ada_op_print_tab, /* expression operators for printing */ diff --git a/gdb/c-lang.c b/gdb/c-lang.c index 9ccb87f..d24b0c8 100644 --- a/gdb/c-lang.c +++ b/gdb/c-lang.c @@ -856,6 +856,7 @@ const struct language_defn c_language_defn = basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_transparent_type,/* lookup_transparent_type */ NULL, /* Language specific symbol demangler */ + NULL, NULL, /* Language specific class_name_from_physname */ c_op_print_tab, /* expression operators for printing */ @@ -989,6 +990,7 @@ const struct language_defn cplus_language_defn = cp_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ cp_lookup_transparent_type, /* lookup_transparent_type */ gdb_demangle, /* Language specific symbol demangler */ + gdb_sniff_from_mangled_name, cp_class_name_from_physname, /* Language specific class_name_from_physname */ c_op_print_tab, /* expression operators for printing */ @@ -1040,6 +1042,7 @@ const struct language_defn asm_language_defn = basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_transparent_type,/* lookup_transparent_type */ NULL, /* Language specific symbol demangler */ + NULL, NULL, /* Language specific class_name_from_physname */ c_op_print_tab, /* expression operators for printing */ @@ -1091,6 +1094,7 @@ const struct language_defn minimal_language_defn = basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_transparent_type,/* lookup_transparent_type */ NULL, /* Language specific symbol demangler */ + NULL, NULL, /* Language specific class_name_from_physname */ c_op_print_tab, /* expression operators for printing */ diff --git a/gdb/cp-support.c b/gdb/cp-support.c index 5662f86..ea6dcb2 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -1627,6 +1627,15 @@ gdb_demangle (const char *name, int options) return result; } +/* See cp-support.h. */ + +int +gdb_sniff_from_mangled_name (const char *mangled, char **demangled) +{ + *demangled = gdb_demangle (mangled, DMGL_PARAMS | DMGL_ANSI); + return *demangled != NULL; +} + /* Don't allow just "maintenance cplus". */ static void diff --git a/gdb/cp-support.h b/gdb/cp-support.h index 78749c8..23ffd71 100644 --- a/gdb/cp-support.h +++ b/gdb/cp-support.h @@ -158,4 +158,8 @@ extern struct cmd_list_element *maint_cplus_cmd_list; char *gdb_demangle (const char *name, int options); +/* Like gdb_demangle, but suitable for use as la_sniff_from_mangled_name. */ + +int gdb_sniff_from_mangled_name (const char *mangled, char **demangled); + #endif /* CP_SUPPORT_H */ diff --git a/gdb/d-lang.c b/gdb/d-lang.c index b25136d..2eb7ffa 100644 --- a/gdb/d-lang.c +++ b/gdb/d-lang.c @@ -55,6 +55,15 @@ d_demangle (const char *symbol, int options) return gdb_demangle (symbol, options | DMGL_DLANG); } +/* la_sniff_from_mangled_name implementation for D. */ + +static int +d_sniff_from_mangled_name (const char *mangled, char **demangled) +{ + *demangled = d_demangle (mangled, 0); + return *demangled != NULL; +} + /* Table mapping opcodes into strings for printing operators and precedences of the operators. */ static const struct op_print d_op_print_tab[] = @@ -223,6 +232,7 @@ static const struct language_defn d_language_defn = d_lookup_symbol_nonlocal, basic_lookup_transparent_type, d_demangle, /* Language specific symbol demangler. */ + d_sniff_from_mangled_name, NULL, /* Language specific class_name_from_physname. */ d_op_print_tab, /* Expression operators for printing. */ @@ -194,26 +194,36 @@ extern void quit_serial_event_clear (void); /* * Languages represented in the symbol table and elsewhere. This should probably be in language.h, but since enum's can't be forward declared to satisfy opaque references before their - actual definition, needs to be here. */ + actual definition, needs to be here. + + The constants here are in priority order. In particular, + demangling is attempted according to this order. + + Note that there's ambiguity between the mangling schemes of some of + these languages, so some symbols could be successfully demangled by + several languages. For that reason, the constants here are sorted + in the order we'll attempt demangling them. For example: Java and + Rust use C++ mangling, so must come after C++; Ada must come last + (see ada_sniff_from_mangled_name). */ enum language { language_unknown, /* Language not known */ language_auto, /* Placeholder for automatic setting */ language_c, /* C */ + language_objc, /* Objective-C */ language_cplus, /* C++ */ + language_java, /* Java */ language_d, /* D */ language_go, /* Go */ - language_objc, /* Objective-C */ - language_java, /* Java */ language_fortran, /* Fortran */ language_m2, /* Modula-2 */ language_asm, /* Assembly language */ language_pascal, /* Pascal */ - language_ada, /* Ada */ language_opencl, /* OpenCL */ language_rust, /* Rust */ language_minimal, /* All other languages, minimal support only */ + language_ada, /* Ada */ nr_languages }; diff --git a/gdb/f-lang.c b/gdb/f-lang.c index 719083b..58f58dd 100644 --- a/gdb/f-lang.c +++ b/gdb/f-lang.c @@ -268,7 +268,14 @@ const struct language_defn f_language_defn = NULL, /* name_of_this */ cp_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_transparent_type,/* lookup_transparent_type */ + + /* We could support demangling here to provide module namespaces + also for inferiors with only minimal symbol table (ELF symbols). + Just the mangling standard is not standardized across compilers + and there is no DW_AT_producer available for inferiors with only + the ELF symbols to check the mangling kind. */ NULL, /* Language specific symbol demangler */ + NULL, NULL, /* Language specific class_name_from_physname */ f_op_print_tab, /* expression operators for printing */ diff --git a/gdb/go-lang.c b/gdb/go-lang.c index 15ca78b..0a0101d 100644 --- a/gdb/go-lang.c +++ b/gdb/go-lang.c @@ -385,6 +385,15 @@ go_demangle (const char *mangled_name, int options) return result; } +/* la_sniff_from_mangled_name for Go. */ + +static int +go_sniff_from_mangled_name (const char *mangled, char **demangled) +{ + *demangled = go_demangle (mangled, 0); + return *demangled != NULL; +} + /* Given a Go symbol, return its package or NULL if unknown. Space for the result is malloc'd, caller must free. */ @@ -584,6 +593,7 @@ static const struct language_defn go_language_defn = basic_lookup_symbol_nonlocal, basic_lookup_transparent_type, go_demangle, /* Language specific symbol demangler. */ + go_sniff_from_mangled_name, NULL, /* Language specific class_name_from_physname. */ go_op_print_tab, /* Expression operators for printing. */ diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c index 797a7f0..bc2fc62 100644 --- a/gdb/jv-lang.c +++ b/gdb/jv-lang.c @@ -1018,6 +1018,15 @@ static char *java_demangle (const char *mangled, int options) return gdb_demangle (mangled, options | DMGL_JAVA); } +/* la_sniff_from_mangled_name for Java. */ + +static int +java_sniff_from_mangled_name (const char *mangled, char **demangled) +{ + *demangled = java_demangle (mangled, DMGL_PARAMS | DMGL_ANSI); + return *demangled != NULL; +} + /* Find the member function name of the demangled name NAME. NAME must be a method name including arguments, in order to correctly locate the last component. @@ -1194,6 +1203,7 @@ const struct language_defn java_language_defn = basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_transparent_type,/* lookup_transparent_type */ java_demangle, /* Language specific symbol demangler */ + java_sniff_from_mangled_name, java_class_name_from_physname,/* Language specific class name */ java_op_print_tab, /* expression operators for printing */ 0, /* not c-style arrays */ diff --git a/gdb/language.c b/gdb/language.c index 02e21ca..f761002 100644 --- a/gdb/language.c +++ b/gdb/language.c @@ -663,6 +663,23 @@ language_demangle (const struct language_defn *current_language, return NULL; } +/* See langauge.h. */ + +int +language_sniff_from_mangled_name (const struct language_defn *lang, + const char *mangled, char **demangled) +{ + gdb_assert (lang != NULL); + + if (lang->la_sniff_from_mangled_name == NULL) + { + *demangled = NULL; + return 0; + } + + return lang->la_sniff_from_mangled_name (mangled, demangled); +} + /* Return class name from physname or NULL. */ char * language_class_name_from_physname (const struct language_defn *lang, @@ -843,6 +860,7 @@ const struct language_defn unknown_language_defn = basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_transparent_type,/* lookup_transparent_type */ unk_lang_demangle, /* Language specific symbol demangler */ + NULL, unk_lang_class_name, /* Language specific class_name_from_physname */ unk_op_print_tab, /* expression operators for printing */ @@ -891,6 +909,7 @@ const struct language_defn auto_language_defn = basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_transparent_type,/* lookup_transparent_type */ unk_lang_demangle, /* Language specific symbol demangler */ + NULL, unk_lang_class_name, /* Language specific class_name_from_physname */ unk_op_print_tab, /* expression operators for printing */ @@ -937,6 +956,7 @@ const struct language_defn local_language_defn = basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_transparent_type,/* lookup_transparent_type */ unk_lang_demangle, /* Language specific symbol demangler */ + NULL, unk_lang_class_name, /* Language specific class_name_from_physname */ unk_op_print_tab, /* expression operators for printing */ diff --git a/gdb/language.h b/gdb/language.h index d57c60e..d6f932e 100644 --- a/gdb/language.h +++ b/gdb/language.h @@ -292,6 +292,22 @@ struct language_defn /* Return demangled language symbol, or NULL. */ char *(*la_demangle) (const char *mangled, int options); + /* Demangle a symbol according to this language's rules. Unlike + la_demangle, this does not take any options. + + *DEMANGLED will be set by this function. + + If this function returns 0, then *DEMANGLED must always be set + to NULL. + + If this function returns 1, the implementation may set this to + a xmalloc'd string holding the demangled form. However, it is + not required to. The string, if any, is owned by the caller. + + The resulting string should be of the form that will be + installed into a symbol. */ + int (*la_sniff_from_mangled_name) (const char *mangled, char **demangled); + /* Return class name of a mangled method name or NULL. */ char *(*la_class_name_from_physname) (const char *physname); @@ -565,6 +581,13 @@ extern CORE_ADDR skip_language_trampoline (struct frame_info *, CORE_ADDR pc); extern char *language_demangle (const struct language_defn *current_language, const char *mangled, int options); +/* A wrapper for la_sniff_from_mangled_name. The arguments and result + are as for the method. */ + +extern int language_sniff_from_mangled_name (const struct language_defn *lang, + const char *mangled, + char **demangled); + /* Return class name from physname, or NULL. */ extern char *language_class_name_from_physname (const struct language_defn *, const char *physname); diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c index 4626bfc..67d0f6b 100644 --- a/gdb/m2-lang.c +++ b/gdb/m2-lang.c @@ -381,6 +381,7 @@ const struct language_defn m2_language_defn = basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_transparent_type,/* lookup_transparent_type */ NULL, /* Language specific symbol demangler */ + NULL, NULL, /* Language specific class_name_from_physname */ m2_op_print_tab, /* expression operators for printing */ diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c index fe3e082..b2844b9 100644 --- a/gdb/objc-lang.c +++ b/gdb/objc-lang.c @@ -281,6 +281,15 @@ objc_demangle (const char *mangled, int options) return NULL; /* Not an objc mangled name. */ } +/* la_sniff_from_mangled_name for ObjC. */ + +static int +objc_sniff_from_mangled_name (const char *mangled, char **demangled) +{ + *demangled = objc_demangle (mangled, 0); + return *demangled != NULL; +} + /* Determine if we are currently in the Objective-C dispatch function. If so, get the address of the method function that the dispatcher would call and use that as the function to step into instead. Also @@ -381,6 +390,7 @@ const struct language_defn objc_language_defn = { basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_transparent_type,/* lookup_transparent_type */ objc_demangle, /* Language specific symbol demangler */ + objc_sniff_from_mangled_name, NULL, /* Language specific class_name_from_physname */ objc_op_print_tab, /* Expression operators for printing */ diff --git a/gdb/opencl-lang.c b/gdb/opencl-lang.c index 74651bc..2a46d86 100644 --- a/gdb/opencl-lang.c +++ b/gdb/opencl-lang.c @@ -1070,6 +1070,7 @@ const struct language_defn opencl_language_defn = basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_transparent_type,/* lookup_transparent_type */ NULL, /* Language specific symbol demangler */ + NULL, NULL, /* Language specific class_name_from_physname */ c_op_print_tab, /* expression operators for printing */ diff --git a/gdb/p-lang.c b/gdb/p-lang.c index 0897be2..86e787b 100644 --- a/gdb/p-lang.c +++ b/gdb/p-lang.c @@ -444,6 +444,7 @@ const struct language_defn pascal_language_defn = basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_transparent_type,/* lookup_transparent_type */ NULL, /* Language specific symbol demangler */ + NULL, NULL, /* Language specific class_name_from_physname */ pascal_op_print_tab, /* expression operators for printing */ 1, /* c-style arrays */ diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c index 36dab67..3b4bcd5 100644 --- a/gdb/rust-lang.c +++ b/gdb/rust-lang.c @@ -25,6 +25,7 @@ #include "c-lang.h" #include "charset.h" #include "cp-support.h" +#include "demangle.h" #include "gdbarch.h" #include "infcall.h" #include "objfiles.h" @@ -1988,6 +1989,17 @@ rust_lookup_symbol_nonlocal (const struct language_defn *langdef, +/* la_sniff_from_mangled_name for Rust. */ + +static int +rust_sniff_from_mangled_name (const char *mangled, char **demangled) +{ + *demangled = gdb_demangle (mangled, DMGL_PARAMS | DMGL_ANSI); + return *demangled != NULL; +} + + + static const struct exp_descriptor exp_descriptor_rust = { rust_print_subexp, @@ -2030,6 +2042,7 @@ static const struct language_defn rust_language_defn = rust_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_transparent_type,/* lookup_transparent_type */ gdb_demangle, /* Language specific symbol demangler */ + rust_sniff_from_mangled_name, NULL, /* Language specific class_name_from_physname */ c_op_print_tab, /* expression operators for printing */ diff --git a/gdb/symtab.c b/gdb/symtab.c index f7a207a..5c4305d 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -747,111 +747,32 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol, const char *mangled) { char *demangled = NULL; + int i; + int recognized; if (gsymbol->language == language_unknown) gsymbol->language = language_auto; - if (gsymbol->language == language_objc - || gsymbol->language == language_auto) - { - demangled = - objc_demangle (mangled, 0); - if (demangled != NULL) - { - gsymbol->language = language_objc; - return demangled; - } - } - if (gsymbol->language == language_cplus - || gsymbol->language == language_rust - || gsymbol->language == language_auto) - { - demangled = - gdb_demangle (mangled, DMGL_PARAMS | DMGL_ANSI); - if (demangled != NULL) - { - gsymbol->language = language_cplus; - return demangled; - } - } - if (gsymbol->language == language_java) + if (gsymbol->language != language_auto) { - demangled = - gdb_demangle (mangled, - DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA); - if (demangled != NULL) - { - gsymbol->language = language_java; - return demangled; - } - } - if (gsymbol->language == language_d - || gsymbol->language == language_auto) - { - demangled = d_demangle(mangled, 0); - if (demangled != NULL) - { - gsymbol->language = language_d; - return demangled; - } + const struct language_defn *lang = language_def (gsymbol->language); + + language_sniff_from_mangled_name (lang, mangled, &demangled); + return demangled; } - /* FIXME(dje): Continually adding languages here is clumsy. - Better to just call la_demangle if !auto, and if auto then call - a utility routine that tries successive languages in turn and reports - which one it finds. I realize the la_demangle options may be different - for different languages but there's already a FIXME for that. */ - if (gsymbol->language == language_go - || gsymbol->language == language_auto) + + for (i = language_unknown; i < nr_languages; ++i) { - demangled = go_demangle (mangled, 0); - if (demangled != NULL) + enum language l = (enum language) i; + const struct language_defn *lang = language_def (l); + + if (language_sniff_from_mangled_name (lang, mangled, &demangled)) { - gsymbol->language = language_go; + gsymbol->language = l; return demangled; } } - /* We could support `gsymbol->language == language_fortran' here to provide - module namespaces also for inferiors with only minimal symbol table (ELF - symbols). Just the mangling standard is not standardized across compilers - and there is no DW_AT_producer available for inferiors with only the ELF - symbols to check the mangling kind. */ - - /* Check for Ada symbols last. See comment below explaining why. */ - - if (gsymbol->language == language_auto) - { - const char *demangled = ada_decode (mangled); - - if (demangled != mangled && demangled != NULL && demangled[0] != '<') - { - /* Set the gsymbol language to Ada, but still return NULL. - Two reasons for that: - - 1. For Ada, we prefer computing the symbol's decoded name - on the fly rather than pre-compute it, in order to save - memory (Ada projects are typically very large). - - 2. There are some areas in the definition of the GNAT - encoding where, with a bit of bad luck, we might be able - to decode a non-Ada symbol, generating an incorrect - demangled name (Eg: names ending with "TB" for instance - are identified as task bodies and so stripped from - the decoded name returned). - - Returning NULL, here, helps us get a little bit of - the best of both worlds. Because we're last, we should - not affect any of the other languages that were able to - demangle the symbol before us; we get to correctly tag - Ada symbols as such; and even if we incorrectly tagged - a non-Ada symbol, which should be rare, any routing - through the Ada language should be transparent (Ada - tries to behave much like C/C++ with non-Ada symbols). */ - gsymbol->language = language_ada; - return NULL; - } - } - return NULL; } |