diff options
Diffstat (limited to 'gdb/c-lang.c')
-rw-r--r-- | gdb/c-lang.c | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/gdb/c-lang.c b/gdb/c-lang.c index f86e26e..a65002c 100644 --- a/gdb/c-lang.c +++ b/gdb/c-lang.c @@ -34,6 +34,9 @@ #include "gdb_obstack.h" #include <ctype.h> #include "gdbcore.h" +#include "symtab.h" +#include "block.h" +#include "linespec.h" /* for find_toplevel_char */ /* Given a C string type, STR_TYPE, return the corresponding target character set name. */ @@ -717,6 +720,68 @@ c_watch_location_expression (struct type *type, CORE_ADDR addr) (xstrprintf ("* (%s *) %s", name.c_str (), core_addr_to_string (addr))); } +/* Compute the C++ hash for STRING0. + + For dictionaries, we group like-symbols together. + That means that all templates with the same unparameterized names + must yield the same hash. Likewise, overloaded functions must also + yield the same hash. + + The following code deals largely with templates. The dreaded + strcmp_iw already enforces overloads to be grouped. */ + +static unsigned int +cplus_compute_string_hash (const char *string0) +{ + /* If '<' doesn't appear at all in STRING), there is no way we could + be dealing with a template name. */ + if (find_toplevel_char (string0, '<') == NULL) + return default_compute_string_hash (string0); + + /* Locate the last qualified component of STRING0. */ + const char *p = find_toplevel_string (string0, "::"); + const char *last_scope = NULL; + + while (p != NULL) + { + last_scope = p; + p = find_toplevel_string (p + 2, "::"); + } + + /* last_scope points to the last "::". If NULL, then no scope operator + was seen in STRING0, and we use the entire string. */ + if (last_scope == NULL) + last_scope = string0; + + /* Find a possible template parameter list. Valid operators will be + dealt with later. */ + p = find_toplevel_char (last_scope, '<'); + + /* P points to toplevel '<', but it could still be a valid operator + and not be a template at all. */ + if ((p - last_scope) > 8 && strncmp (p - 8, "operator", 8) == 0) + { + /* Skip <,=. */ + while (strchr ("<=", *p) != NULL) + ++p; + + /* Check if this operator contains a template parameter list marker. */ + p = find_toplevel_char (p, '<'); + } + + /* If NULL, the string represents an operator (<, <=, <<, <<=) and is not + a template function itself. */ + if (p == NULL) + return default_compute_string_hash (string0); + + char *copy = ASTRDUP (string0); + + copy[p - string0] = '\0'; + + /* It is a template, compute the hash based only until P. */ + return default_compute_string_hash (copy); +} + /* Table mapping opcodes into strings for printing operators and precedences of the operators. */ @@ -871,6 +936,7 @@ extern const struct language_defn c_language_defn = c_watch_location_expression, NULL, /* la_get_symbol_name_cmp */ iterate_over_symbols, + default_compute_string_hash, &c_varobj_ops, c_get_compile_context, c_compute_program, @@ -1015,9 +1081,10 @@ extern const struct language_defn cplus_language_defn = c_watch_location_expression, NULL, /* la_get_symbol_name_cmp */ iterate_over_symbols, + cplus_compute_string_hash, &cplus_varobj_ops, - NULL, - NULL, + cplus_get_compile_context, + cplus_compute_program, LANG_MAGIC }; @@ -1068,6 +1135,7 @@ extern const struct language_defn asm_language_defn = c_watch_location_expression, NULL, /* la_get_symbol_name_cmp */ iterate_over_symbols, + default_compute_string_hash, &default_varobj_ops, NULL, NULL, @@ -1121,6 +1189,7 @@ extern const struct language_defn minimal_language_defn = c_watch_location_expression, NULL, /* la_get_symbol_name_cmp */ iterate_over_symbols, + default_compute_string_hash, &default_varobj_ops, NULL, NULL, |