Re: [RFA 3/3] Move logic out of symbol_find_demangled_name

Tom Tromey
2016-06-24T03:15:48Z

Pedro> I think I'd prefer it close to where the order is defined.
Pedro> But maybe there is OK as well; hard to say without seeing.
Pedro> Maybe do both, and everyone's happy.

I copied your text verbatim into the comment before "enum language".

This series is fully approved, so I am going to check it in.

Tom

commit 8b302db80cb07f5f3264b50e1b51fdb8ecb29183
Author: Tom Tromey <tom@tromey.com>
Date: Thu May 26 15:04:07 2016 -0600

Move logic out of symbol_find_demangled_name

This patch moves most of the demangling logic out of
symbol_find_demangled_name into the various language_defn objects.

The simplest way to do this seemed to be to add a new method to
language_defn. This is shame given the existing la_demangle, but
given Ada's unusual needs, and the differing demangling options
between languages, la_demangle didn't seem to fit.

In order to make this work, I made enum language order-sensitive.
This helps preserve the current ordering of demangling operations.

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.

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. */
diff --git a/gdb/defs.h b/gdb/defs.h
index b81de46..5088390 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -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,

\f

+/* 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;
+}
+
+\f
+
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;
}