diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c index 5e894d4..85082ce 100644 --- a/gdb/cp-namespace.c +++ b/gdb/cp-namespace.c @@ -117,7 +117,7 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol) anonymous namespace. So add symbols in it to the namespace given by the previous component if there is one, or to the global namespace if there isn't. */ - cp_add_using_directive (dest, src, NULL); + cp_add_using_directive (dest, src, NULL, NULL); } /* The "+ 2" is for the "::". */ previous_component = next_component + 2; @@ -132,7 +132,10 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol) has already been added, don't add it twice. */ void -cp_add_using_directive (const char *dest, const char *src, const char *alias) +cp_add_using_directive (const char *dest, + const char *src, + const char *alias, + const char *declaration) { struct using_direct *current; struct using_direct *new; @@ -146,8 +149,8 @@ cp_add_using_directive (const char *dest, const char *src, const char *alias) return; } - using_directives = cp_add_using (dest, src, alias, using_directives); - + using_directives = cp_add_using (dest, src, alias, declaration, + using_directives); } /* Record the namespace that the function defined by SYMBOL was @@ -209,18 +212,22 @@ struct using_direct * cp_add_using (const char *dest, const char *src, const char *alias, + const char *declaration, struct using_direct *next) { struct using_direct *retval; retval = xmalloc (sizeof (struct using_direct)); + memset (retval, 0, sizeof (struct using_direct)); + retval->import_src = savestring (src, strlen(src)); retval->import_dest = savestring (dest, strlen(dest)); if (alias != NULL) retval->alias = savestring (alias, strlen (alias)); - else - retval->alias = NULL; + + if (declaration != NULL) + retval->declaration = savestring (declaration, strlen (declaration)); retval->next = next; retval->searched = 0; @@ -249,11 +256,10 @@ cp_lookup_symbol_nonlocal (const char *name, if (sym != NULL) return sym; - return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain, - 1); + return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain); } -/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in +/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in cp_lookup_symbol_nonlocal. */ static struct symbol * @@ -304,26 +310,28 @@ reset_directive_searched (void *data) } If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of namespaces X - and Y will be considered. If SEARCH_PARENTS is false only the import of Y + and Y will be considered. If SEARCH_PARENTS is false only the import of Y is considered. */ -static struct symbol * +struct symbol * cp_lookup_symbol_imports (const char *scope, const char *name, const char *linkage_name, const struct block *block, const domain_enum domain, + const int declaration_only, const int search_parents) { struct using_direct *current; - struct symbol *sym; + struct symbol *sym = NULL; int len; int directive_match; struct cleanup *searched_cleanup; /* First, try to find the symbol in the given namespace. */ - sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block, - domain); + if (!declaration_only) + sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block, + domain); if (sym != NULL) return sym; @@ -352,6 +360,31 @@ cp_lookup_symbol_imports (const char *scope, current->searched = 1; searched_cleanup = make_cleanup (reset_directive_searched, current); + /* If there is an import of a single declaration, compare the imported + declaration with the sought out name. If there is a match pass + current->import_src as NAMESPACE to direct the search towards the + imported namespace. */ + if (current->declaration && strcmp (name, current->declaration) == 0) + sym = cp_lookup_symbol_in_namespace (current->import_src, + name, + linkage_name, + block, + domain); + + /* If this is a DECLARATION_ONLY search or a symbol was found or + this import statement was an import declaration, the search + of this import is complete. */ + if (declaration_only || sym != NULL || current->declaration) + { + current->searched = 0; + discard_cleanups (searched_cleanup); + + if (sym != NULL) + return sym; + + continue; + } + if (current->alias != NULL && strcmp (name, current->alias) == 0) /* If the import is creating an alias and the alias matches the sought name. Pass current->import_src as the NAME to direct the @@ -372,6 +405,7 @@ cp_lookup_symbol_imports (const char *scope, linkage_name, block, domain, + 0, 0); } current->searched = 0; @@ -394,16 +428,21 @@ cp_lookup_symbol_namespace (const char *scope, const char *name, const char *linkage_name, const struct block *block, - const domain_enum domain, - const int search_parents) + const domain_enum domain) { struct symbol *sym; + /* First, try to find the symbol in the given namespace. */ + sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block, + domain); + if ( sym != NULL) + return sym; + /* Search for name in namespaces imported to this and parent blocks. */ while (block != NULL) { sym = cp_lookup_symbol_imports (scope, name, linkage_name, block, domain, - search_parents); + 0, 1); if (sym) return sym; diff --git a/gdb/cp-support.h b/gdb/cp-support.h index a6a9af1..8e7abc6 100644 --- a/gdb/cp-support.h +++ b/gdb/cp-support.h @@ -44,6 +44,11 @@ struct demangle_component; Eg: namespace C = A::B; ALIAS = "C" + DECLARATION is the name of the imported declaration, if this import + statement represents one. + Eg: + using A::x; + Where x is variable in namespace A. DECLARATION is set to x. */ struct using_direct @@ -52,6 +57,7 @@ struct using_direct char *import_dest; char *alias; + char *declaration; struct using_direct *next; @@ -90,11 +96,13 @@ extern int cp_is_anonymous (const char *namespace); extern void cp_add_using_directive (const char *dest, const char *src, - const char *alias); + const char *alias, + const char *declaration); extern struct using_direct *cp_add_using (const char *dest, const char *src, const char *alias, + const char *declaration, struct using_direct *next); extern void cp_initialize_namespace (void); @@ -119,8 +127,15 @@ extern struct symbol *cp_lookup_symbol_namespace (const char *namespace, const char *name, const char *linkage_name, const struct block *block, - const domain_enum domain, - const int search_parents); + const domain_enum domain); + +extern struct symbol *cp_lookup_symbol_imports (const char *scope, + const char *name, + const char *linkage_name, + const struct block *block, + const domain_enum domain, + const int declaration_only, + const int search_parents); extern struct type *cp_lookup_nested_type (struct type *parent_type, const char *nested_name, diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index a05c946..04cdd34 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -3385,10 +3385,10 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) struct dwarf2_cu *imported_cu; const char *imported_name; const char *imported_name_prefix; - char *import_alias; - - const char *import_prefix; char *canonical_name; + const char *import_alias; + const char *imported_declaration = NULL; + const char *import_prefix; import_attr = dwarf2_attr (die, DW_AT_import, cu); if (import_attr == NULL) @@ -3448,23 +3448,32 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) to the name of the imported die. */ imported_name_prefix = determine_prefix (imported_die, imported_cu); - if (strlen (imported_name_prefix) > 0) + if (imported_die->tag != DW_TAG_namespace) { - canonical_name = alloca (strlen (imported_name_prefix) - + 2 + strlen (imported_name) + 1); - strcpy (canonical_name, imported_name_prefix); - strcat (canonical_name, "::"); - strcat (canonical_name, imported_name); + imported_declaration = imported_name; + canonical_name = (char *) imported_name_prefix; } else { - canonical_name = alloca (strlen (imported_name) + 1); - strcpy (canonical_name, imported_name); + if (strlen (imported_name_prefix) > 0) + { + canonical_name = alloca (strlen (imported_name_prefix) + + 2 + strlen (imported_name) + 1); + strcpy (canonical_name, imported_name_prefix); + strcat (canonical_name, "::"); + strcat (canonical_name, imported_name); + } + else + { + canonical_name = alloca (strlen (imported_name) + 1); + strcpy (canonical_name, imported_name); + } } using_directives = cp_add_using (import_prefix, canonical_name, import_alias, + imported_declaration, using_directives); } @@ -5624,7 +5633,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu) if (is_anonymous) { const char *previous_prefix = determine_prefix (die, cu); - cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL); + cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL, NULL); } } diff --git a/gdb/eval.c b/gdb/eval.c index e2ceea7..f48b392 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -1435,7 +1435,7 @@ evaluate_subexp_standard (struct type *expect_type, function = cp_lookup_symbol_namespace (TYPE_TAG_NAME (type), name, NULL, get_selected_block (0), - VAR_DOMAIN, 1); + VAR_DOMAIN); if (function == NULL) error (_("No symbol \"%s\" in namespace \"%s\"."), name, TYPE_TAG_NAME (type)); diff --git a/gdb/symtab.c b/gdb/symtab.c index af4e501..45e09df 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -95,7 +95,8 @@ static struct symbol *lookup_symbol_aux_local (const char *name, const char *linkage_name, const struct block *block, - const domain_enum domain); + const domain_enum domain, + enum language language); static struct symbol *lookup_symbol_aux_symtabs (int block_index, @@ -1354,15 +1355,14 @@ lookup_symbol_aux (const char *name, const char *linkage_name, /* Search specified block and its superiors. Don't search STATIC_BLOCK or GLOBAL_BLOCK. */ - sym = lookup_symbol_aux_local (name, linkage_name, block, domain); + sym = lookup_symbol_aux_local (name, linkage_name, block, domain, language); if (sym != NULL) return sym; /* If requested to do so by the caller and if appropriate for LANGUAGE, - check to see if NAME is a field of `this'. */ + check to see if NAME is a field of `this'. */ langdef = language_def (language); - if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL && block != NULL) { @@ -1430,10 +1430,12 @@ lookup_symbol_aux (const char *name, const char *linkage_name, static struct symbol * lookup_symbol_aux_local (const char *name, const char *linkage_name, const struct block *block, - const domain_enum domain) + const domain_enum domain, + enum language language) { struct symbol *sym; const struct block *static_block = block_static_block (block); + const char *scope = block_scope (block); /* Check if either no block is specified or it's a global block. */ @@ -1446,6 +1448,13 @@ lookup_symbol_aux_local (const char *name, const char *linkage_name, if (sym != NULL) return sym; + if (language == language_cplus ) + { + sym = cp_lookup_symbol_imports (scope, name, linkage_name, block, domain, 1, 1); + if (sym != NULL) + return sym; + } + if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block)) break; block = BLOCK_SUPERBLOCK (block); diff --git a/gdb/testsuite/gdb.cp/nsusing.exp b/gdb/testsuite/gdb.cp/nsusing.exp index 72a616e..b060ee2 100644 --- a/gdb/testsuite/gdb.cp/nsusing.exp +++ b/gdb/testsuite/gdb.cp/nsusing.exp @@ -154,7 +154,7 @@ if ![runto marker4] then { perror "couldn't run to breakpoint marker4" continue } -setup_kfail "gdb/7936" "*-*-*" + gdb_test "print dx" "= 4" ############################################ diff --git a/gdb/testsuite/gdb.cp/shadow.cc b/gdb/testsuite/gdb.cp/shadow.cc index 1651510..0520b2a 100644 --- a/gdb/testsuite/gdb.cp/shadow.cc +++ b/gdb/testsuite/gdb.cp/shadow.cc @@ -29,8 +29,10 @@ public: using namespace A; y++; // marker4 - using A::x; - y++; // marker5 + { + using A::x; + y++; // marker5 + } } } } diff --git a/gdb/testsuite/gdb.cp/shadow.exp b/gdb/testsuite/gdb.cp/shadow.exp index 1e5e80b..40c35a4 100644 --- a/gdb/testsuite/gdb.cp/shadow.exp +++ b/gdb/testsuite/gdb.cp/shadow.exp @@ -85,5 +85,4 @@ gdb_test "print x" "= 55" "Print local x not namespace x" gdb_breakpoint [gdb_get_line_number "marker5"] gdb_continue_to_breakpoint "marker5" -setup_kfail "gdb/7936" "*-*-*" gdb_test "print x" "= 11" "Print imported namespace x" diff --git a/gdb/valops.c b/gdb/valops.c index b94c411..b5e47d3 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -3119,7 +3119,7 @@ value_maybe_namespace_elt (const struct type *curtype, sym = cp_lookup_symbol_namespace (namespace_name, name, NULL, get_selected_block (0), - VAR_DOMAIN, 1); + VAR_DOMAIN); if (sym == NULL) return NULL;