X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fcp-support.c;h=9970f0ca8643fa09631d1989fe13a60257363da4;hb=d55e5aa6b29906346c51ad00e6a9b112590aa294;hp=172d8219f475bc01687e2fa546b59dc9b99acf30;hpb=a20714ff39f621961151d0c204e89062ab2107eb;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/cp-support.c b/gdb/cp-support.c index 172d8219f4..9970f0ca86 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -1,5 +1,5 @@ /* Helper routines for C++ support in GDB. - Copyright (C) 2002-2017 Free Software Foundation, Inc. + Copyright (C) 2002-2019 Free Software Foundation, Inc. Contributed by MontaVista Software. @@ -19,24 +19,28 @@ along with this program. If not, see . */ #include "defs.h" + +/* Standard C includes. */ +#include + +/* Local non-gdb includes. */ +#include "block.h" +#include "common/gdb_setjmp.h" +#include "common/selftest.h" +#include "complaints.h" +#include "cp-abi.h" #include "cp-support.h" #include "demangle.h" -#include "gdbcmd.h" #include "dictionary.h" -#include "objfiles.h" +#include "expression.h" #include "frame.h" -#include "symtab.h" -#include "block.h" -#include "complaints.h" +#include "gdbcmd.h" #include "gdbtypes.h" -#include "expression.h" -#include "value.h" -#include "cp-abi.h" #include "namespace.h" -#include -#include "gdb_setjmp.h" +#include "objfiles.h" #include "safe-ctype.h" -#include "selftest.h" +#include "symtab.h" +#include "value.h" #define d_left(dc) (dc)->u.s_binary.left #define d_right(dc) (dc)->u.s_binary.right @@ -48,19 +52,19 @@ static unsigned int cp_find_first_component_aux (const char *name, static void demangled_name_complaint (const char *name); -/* Functions/variables related to overload resolution. */ - -static int sym_return_val_size = -1; -static int sym_return_val_index; -static struct symbol **sym_return_val; +/* Functions related to overload resolution. */ static void overload_list_add_symbol (struct symbol *sym, - const char *oload_name); + const char *oload_name, + std::vector *overload_list); -static void make_symbol_overload_list_using (const char *func_name, - const char *the_namespace); +static void add_symbol_overload_list_using + (const char *func_name, const char *the_namespace, + std::vector *overload_list); -static void make_symbol_overload_list_qualified (const char *func_name); +static void add_symbol_overload_list_qualified + (const char *func_name, + std::vector *overload_list); /* The list of "maint cplus" commands. */ @@ -133,7 +137,6 @@ inspect_type (struct demangle_parse_info *info, canonicalization_ftype *finder, void *data) { - int i; char *name; struct symbol *sym; @@ -144,7 +147,7 @@ inspect_type (struct demangle_parse_info *info, name[ret_comp->u.s_name.len] = '\0'; /* Ignore any typedefs that should not be substituted. */ - for (i = 0; i < ARRAY_SIZE (ignore_typedefs); ++i) + for (int i = 0; i < ARRAY_SIZE (ignore_typedefs); ++i) { if (strcmp (name, ignore_typedefs[i]) == 0) return 0; @@ -199,7 +202,7 @@ inspect_type (struct demangle_parse_info *info, && strcmp (TYPE_NAME (type), name) == 0) return 0; - is_anon = (TYPE_TAG_NAME (type) == NULL + is_anon = (TYPE_NAME (type) == NULL && (TYPE_CODE (type) == TYPE_CODE_ENUM || TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION)); @@ -809,10 +812,9 @@ method_name_from_physname (const char *physname) /* If FULL_NAME is the demangled name of a C++ function (including an arg list, possibly including namespace/class qualifications), return a new string containing only the function name (without the - arg list/class qualifications). Otherwise, return NULL. The - caller is responsible for freeing the memory in question. */ + arg list/class qualifications). Otherwise, return NULL. */ -char * +gdb::unique_xmalloc_ptr cp_func_name (const char *full_name) { gdb::unique_xmalloc_ptr ret; @@ -821,14 +823,14 @@ cp_func_name (const char *full_name) info = cp_demangled_name_to_comp (full_name, NULL); if (!info) - return NULL; + return nullptr; ret_comp = unqualified_name_from_comp (info->tree); if (ret_comp != NULL) ret = cp_comp_to_string (ret_comp, 10); - return ret.release (); + return ret; } /* Helper for cp_remove_params. DEMANGLED_NAME is the name of a @@ -1108,8 +1110,7 @@ cp_find_first_component_aux (const char *name, int permissive) static void demangled_name_complaint (const char *name) { - complaint (&symfile_complaints, - "unexpected demangled name '%s'", name); + complaint ("unexpected demangled name '%s'", name); } /* If NAME is the fully-qualified name of a C++ @@ -1139,30 +1140,28 @@ cp_entire_prefix_len (const char *name) /* Overload resolution functions. */ /* Test to see if SYM is a symbol that we haven't seen corresponding - to a function named OLOAD_NAME. If so, add it to the current - completion list. */ + to a function named OLOAD_NAME. If so, add it to + OVERLOAD_LIST. */ static void overload_list_add_symbol (struct symbol *sym, - const char *oload_name) + const char *oload_name, + std::vector *overload_list) { - int newsize; - int i; - gdb::unique_xmalloc_ptr sym_name; - /* If there is no type information, we can't do anything, so skip. */ if (SYMBOL_TYPE (sym) == NULL) return; /* skip any symbols that we've already considered. */ - for (i = 0; i < sym_return_val_index; ++i) + for (symbol *listed_sym : *overload_list) if (strcmp (SYMBOL_LINKAGE_NAME (sym), - SYMBOL_LINKAGE_NAME (sym_return_val[i])) == 0) + SYMBOL_LINKAGE_NAME (listed_sym)) == 0) return; /* Get the demangled name without parameters */ - sym_name = cp_remove_params (SYMBOL_NATURAL_NAME (sym)); + gdb::unique_xmalloc_ptr sym_name + = cp_remove_params (SYMBOL_NATURAL_NAME (sym)); if (!sym_name) return; @@ -1170,36 +1169,22 @@ overload_list_add_symbol (struct symbol *sym, if (strcmp (sym_name.get (), oload_name) != 0) return; - /* We have a match for an overload instance, so add SYM to the - current list of overload instances */ - if (sym_return_val_index + 3 > sym_return_val_size) - { - newsize = (sym_return_val_size *= 2) * sizeof (struct symbol *); - sym_return_val = (struct symbol **) - xrealloc ((char *) sym_return_val, newsize); - } - sym_return_val[sym_return_val_index++] = sym; - sym_return_val[sym_return_val_index] = NULL; + overload_list->push_back (sym); } /* Return a null-terminated list of pointers to function symbols that are named FUNC_NAME and are visible within NAMESPACE. */ -struct symbol ** +struct std::vector make_symbol_overload_list (const char *func_name, const char *the_namespace) { - struct cleanup *old_cleanups; const char *name; + std::vector overload_list; - sym_return_val_size = 100; - sym_return_val_index = 0; - sym_return_val = XNEWVEC (struct symbol *, sym_return_val_size + 1); - sym_return_val[0] = NULL; + overload_list.reserve (100); - old_cleanups = make_cleanup (xfree, sym_return_val); - - make_symbol_overload_list_using (func_name, the_namespace); + add_symbol_overload_list_using (func_name, the_namespace, &overload_list); if (the_namespace[0] == '\0') name = func_name; @@ -1213,19 +1198,17 @@ make_symbol_overload_list (const char *func_name, name = concatenated_name; } - make_symbol_overload_list_qualified (name); - - discard_cleanups (old_cleanups); - - return sym_return_val; + add_symbol_overload_list_qualified (name, &overload_list); + return overload_list; } /* Add all symbols with a name matching NAME in BLOCK to the overload list. */ static void -make_symbol_overload_list_block (const char *name, - const struct block *block) +add_symbol_overload_list_block (const char *name, + const struct block *block, + std::vector *overload_list) { struct block_iterator iter; struct symbol *sym; @@ -1233,14 +1216,15 @@ make_symbol_overload_list_block (const char *name, lookup_name_info lookup_name (name, symbol_name_match_type::FULL); ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym) - overload_list_add_symbol (sym, name); + overload_list_add_symbol (sym, name, overload_list); } /* Adds the function FUNC_NAME from NAMESPACE to the overload set. */ static void -make_symbol_overload_list_namespace (const char *func_name, - const char *the_namespace) +add_symbol_overload_list_namespace (const char *func_name, + const char *the_namespace, + std::vector *overload_list) { const char *name; const struct block *block = NULL; @@ -1261,12 +1245,12 @@ make_symbol_overload_list_namespace (const char *func_name, /* Look in the static block. */ block = block_static_block (get_selected_block (0)); if (block) - make_symbol_overload_list_block (name, block); + add_symbol_overload_list_block (name, block, overload_list); /* Look in the global block. */ block = block_global_block (block); if (block) - make_symbol_overload_list_block (name, block); + add_symbol_overload_list_block (name, block, overload_list); } @@ -1274,8 +1258,9 @@ make_symbol_overload_list_namespace (const char *func_name, base types. */ static void -make_symbol_overload_list_adl_namespace (struct type *type, - const char *func_name) +add_symbol_overload_list_adl_namespace (struct type *type, + const char *func_name, + std::vector *overload_list) { char *the_namespace; const char *type_name; @@ -1305,7 +1290,8 @@ make_symbol_overload_list_adl_namespace (struct type *type, strncpy (the_namespace, type_name, prefix_len); the_namespace[prefix_len] = '\0'; - make_symbol_overload_list_namespace (func_name, the_namespace); + add_symbol_overload_list_namespace (func_name, the_namespace, + overload_list); } /* Check public base type */ @@ -1313,28 +1299,23 @@ make_symbol_overload_list_adl_namespace (struct type *type, for (i = 0; i < TYPE_N_BASECLASSES (type); i++) { if (BASETYPE_VIA_PUBLIC (type, i)) - make_symbol_overload_list_adl_namespace (TYPE_BASECLASS (type, - i), - func_name); + add_symbol_overload_list_adl_namespace (TYPE_BASECLASS (type, i), + func_name, + overload_list); } } -/* Adds the overload list overload candidates for FUNC_NAME found - through argument dependent lookup. */ +/* Adds to OVERLOAD_LIST the overload list overload candidates for + FUNC_NAME found through argument dependent lookup. */ -struct symbol ** -make_symbol_overload_list_adl (struct type **arg_types, int nargs, - const char *func_name) +void +add_symbol_overload_list_adl (gdb::array_view arg_types, + const char *func_name, + std::vector *overload_list) { - int i; - - gdb_assert (sym_return_val_size != -1); - - for (i = 1; i <= nargs; i++) - make_symbol_overload_list_adl_namespace (arg_types[i - 1], - func_name); - - return sym_return_val; + for (type *arg_type : arg_types) + add_symbol_overload_list_adl_namespace (arg_type, func_name, + overload_list); } /* This applies the using directives to add namespaces to search in, @@ -1343,8 +1324,9 @@ make_symbol_overload_list_adl (struct type **arg_types, int nargs, make_symbol_overload_list. */ static void -make_symbol_overload_list_using (const char *func_name, - const char *the_namespace) +add_symbol_overload_list_using (const char *func_name, + const char *the_namespace, + std::vector *overload_list) { struct using_direct *current; const struct block *block; @@ -1376,13 +1358,15 @@ make_symbol_overload_list_using (const char *func_name, scoped_restore reset_directive_searched = make_scoped_restore (¤t->searched, 1); - make_symbol_overload_list_using (func_name, - current->import_src); + add_symbol_overload_list_using (func_name, + current->import_src, + overload_list); } } /* Now, add names for this namespace. */ - make_symbol_overload_list_namespace (func_name, the_namespace); + add_symbol_overload_list_namespace (func_name, the_namespace, + overload_list); } /* This does the bulk of the work of finding overloaded symbols. @@ -1390,54 +1374,59 @@ make_symbol_overload_list_using (const char *func_name, (possibly including namespace info). */ static void -make_symbol_overload_list_qualified (const char *func_name) +add_symbol_overload_list_qualified (const char *func_name, + std::vector *overload_list) { - struct compunit_symtab *cust; - struct objfile *objfile; const struct block *b, *surrounding_static_block = 0; /* Look through the partial symtabs for all symbols which begin by matching FUNC_NAME. Make sure we read that symbol table in. */ - ALL_OBJFILES (objfile) - { - if (objfile->sf) - objfile->sf->qf->expand_symtabs_for_function (objfile, func_name); - } + for (objfile *objf : current_program_space->objfiles ()) + { + if (objf->sf) + objf->sf->qf->expand_symtabs_for_function (objf, func_name); + } /* Search upwards from currently selected frame (so that we can complete on local vars. */ for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b)) - make_symbol_overload_list_block (func_name, b); + add_symbol_overload_list_block (func_name, b, overload_list); surrounding_static_block = block_static_block (get_selected_block (0)); /* Go through the symtabs and check the externs and statics for symbols which match. */ - ALL_COMPUNITS (objfile, cust) - { - QUIT; - b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), GLOBAL_BLOCK); - make_symbol_overload_list_block (func_name, b); - } + for (objfile *objfile : current_program_space->objfiles ()) + { + for (compunit_symtab *cust : objfile->compunits ()) + { + QUIT; + b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), GLOBAL_BLOCK); + add_symbol_overload_list_block (func_name, b, overload_list); + } + } - ALL_COMPUNITS (objfile, cust) - { - QUIT; - b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), STATIC_BLOCK); - /* Don't do this block twice. */ - if (b == surrounding_static_block) - continue; - make_symbol_overload_list_block (func_name, b); - } + for (objfile *objfile : current_program_space->objfiles ()) + { + for (compunit_symtab *cust : objfile->compunits ()) + { + QUIT; + b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), STATIC_BLOCK); + /* Don't do this block twice. */ + if (b == surrounding_static_block) + continue; + add_symbol_overload_list_block (func_name, b, overload_list); + } + } } /* Lookup the rtti type for a class name. */ struct type * -cp_lookup_rtti_type (const char *name, struct block *block) +cp_lookup_rtti_type (const char *name, const struct block *block) { struct symbol * rtti_sym; struct type * rtti_type; @@ -1629,7 +1618,23 @@ cp_search_name_hash (const char *search_name) if (prefix_len != 0) search_name += prefix_len + 2; - return default_search_name_hash (search_name); + unsigned int hash = 0; + for (const char *string = search_name; *string != '\0'; ++string) + { + string = skip_spaces (string); + + if (*string == '(') + break; + + /* Ignore ABI tags such as "[abi:cxx11]. */ + if (*string == '[' + && startswith (string + 1, "abi:") + && string[5] != ':') + break; + + hash = SYMBOL_HASH_NEXT (hash, *string); + } + return hash; } /* Helper for cp_symbol_name_matches (i.e., symbol_name_matcher_ftype @@ -1674,11 +1679,13 @@ cp_symbol_name_matches_1 (const char *symbol_search_name, completion_match_result *comp_match_res) { const char *sname = symbol_search_name; + completion_match_for_lcd *match_for_lcd + = (comp_match_res != NULL ? &comp_match_res->match_for_lcd : NULL); while (true) { if (strncmp_iw_with_mode (sname, lookup_name, lookup_name_len, - mode, language_cplus) == 0) + mode, language_cplus, match_for_lcd) == 0) { if (comp_match_res != NULL) { @@ -1728,14 +1735,15 @@ cp_fq_symbol_name_matches (const char *symbol_search_name, { /* Get the demangled name. */ const std::string &name = lookup_name.cplus ().lookup_name (); - + completion_match_for_lcd *match_for_lcd + = (comp_match_res != NULL ? &comp_match_res->match_for_lcd : NULL); strncmp_iw_mode mode = (lookup_name.completion_mode () ? strncmp_iw_mode::NORMAL : strncmp_iw_mode::MATCH_PARAMS); if (strncmp_iw_with_mode (symbol_search_name, name.c_str (), name.size (), - mode, language_cplus) == 0) + mode, language_cplus, match_for_lcd) == 0) { if (comp_match_res != NULL) comp_match_res->set_match (symbol_search_name); @@ -1774,6 +1782,7 @@ cp_get_symbol_name_matcher (const lookup_name_info &lookup_name) { case symbol_name_match_type::FULL: case symbol_name_match_type::EXPRESSION: + case symbol_name_match_type::SEARCH_NAME: return cp_fq_symbol_name_matches; case symbol_name_match_type::WILD: return cp_symbol_name_matches; @@ -1950,6 +1959,32 @@ test_cp_symbol_name_matches () CHECK_NOT_MATCH_C ("foo::function()", "::function()"); CHECK_NOT_MATCH_C ("foo::function(int)", "::function()"); CHECK_NOT_MATCH_C ("foo::function(int)", "::function(int)"); + + /* Test ABI tag matching/ignoring. */ + + /* If the symbol name has an ABI tag, but the lookup name doesn't, + then the ABI tag in the symbol name is ignored. */ + CHECK_MATCH_C ("function[abi:foo]()", "function"); + CHECK_MATCH_C ("function[abi:foo](int)", "function"); + CHECK_MATCH_C ("function[abi:foo]()", "function ()"); + CHECK_NOT_MATCH_C ("function[abi:foo]()", "function (int)"); + + CHECK_MATCH_C ("function[abi:foo]()", "function[abi:foo]"); + CHECK_MATCH_C ("function[abi:foo](int)", "function[abi:foo]"); + CHECK_MATCH_C ("function[abi:foo]()", "function[abi:foo] ()"); + CHECK_MATCH_C ("function[abi:foo][abi:bar]()", "function"); + CHECK_MATCH_C ("function[abi:foo][abi:bar](int)", "function"); + CHECK_MATCH_C ("function[abi:foo][abi:bar]()", "function[abi:foo]"); + CHECK_MATCH_C ("function[abi:foo][abi:bar](int)", "function[abi:foo]"); + CHECK_MATCH_C ("function[abi:foo][abi:bar]()", "function[abi:foo] ()"); + CHECK_NOT_MATCH_C ("function[abi:foo][abi:bar]()", "function[abi:foo] (int)"); + + CHECK_MATCH_C ("function [abi:foo][abi:bar] ( )", "function [abi:foo]"); + + /* If the symbol name does not have an ABI tag, while the lookup + name has one, then there's no match. */ + CHECK_NOT_MATCH_C ("function()", "function[abi:foo]()"); + CHECK_NOT_MATCH_C ("function()", "function[abi:foo]"); } /* If non-NULL, return STR wrapped in quotes. Otherwise, return a