This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [patch 1/2] Search typedefs in namespaces also in other files
On Wed, 16 Jun 2010 23:30:07 +0200, Tom Tromey wrote:
> >>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:
> Jan> Already the C++ parser calls various functions in not so correct
> Jan> way IMHO
>
> I'm curious to know what.
I am withdrawing that claim. After I found a simple fix for PR 11703 (which
is PR 1448) it started working.
> Jan> [Bug c++/11703] New: root namespace sometimes not working
> Jan> - Leading :: works only for types, not other objects.
> Jan> - IMHO a fix requires patching the C++ parser: -> archer-cpparser
>
> I think it could probably be solved, but that isn't too important.
> We'll fix it one way or another. Thanks for filing that.
It may be fixed by:
- if (first_was_coloncolon)
+ if (first_was_coloncolon && first_iter)
but that I am going to post+investigate it in a different patch.
cp_lookup_symbol_namespace:
> Jan> + /* Now search all static file-level symbols. Not strictly correct,
> Jan> + but more useful than an error. We do not try to guess any imported
> Jan> + namespace as even the fully specified namespace seach is is already not
> Jan> + C++ compliant and more assumptions could make it too magic. */
> Jan> +
> Jan> + if (scope[0] == '\0')
> Jan> + {
> Jan> + sym = lookup_static_symbol_aux (name, domain);
>
> I'm having trouble following all the logic.
>
> I think lookup_symbol_aux calls la_lookup_symbol_nonlocal,
> which for C++ calls cp_lookup_symbol_nonlocal, which calls
> cp_lookup_symbol_namespace.
>
> But maybe this call is needed here for other callers of
> cp_lookup_symbol_namespace?
Yes, also value_maybe_namespace_elt calls it. OK, made two changes: Inlined
the logic into the caller value_maybe_namespace_elt.
This way the (scope[0] == '\0') branch lost its meaning.
> I think you should leave that comment in the previous function and write
> a new comment for lookup_static_symbol_aux.
Made some change. I find "comment in the previous function" describes
internals (="Do the symtabs first, then check the psymtabs.") of the function
being called. Such comment should not be at the caller, should be?
No regressions on {x86_64,x86_64-m32,i686}-fedora13-linux-gnu.
The XFAIL GCC version checks are for FSF GCC (<=4.4). Therefore for recent
Fedora GCCs (gcc-c++-4.4.4-8.fc13) it XPASSes as they behave like FSF GCC-4.5+.
Thanks,
Jan
gdb/
2010-06-25 Jan Kratochvil <jan.kratochvil@redhat.com>
* cp-namespace.c (cp_lookup_nested_type): New variable
concatenated_name. Turn the current return condition into a reverse
one. Call also lookup_static_symbol_aux on the constructed qualified
name.
* symtab.c (lookup_symbol_aux): Move variable objfile and searching in
other files into a called ...
(lookup_static_symbol_aux): ... new function here.
* symtab.h (lookup_static_symbol_aux): New prototype.
* valops.c (value_maybe_namespace_elt): Call also
lookup_static_symbol_aux if we failed otherwise.
gdb/testsuite/
2010-06-25 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.cp/namespace.exp (whatis C::cOtherFileType)
(whatis ::C::cOtherFileType, whatis C::cOtherFileVar)
(whatis ::C::cOtherFileVar, print C::cOtherFileVar)
(print ::C::cOtherFileVar)
(whatis C::OtherFileClass::cOtherFileClassType)
(whatis ::C::OtherFileClass::cOtherFileClassType)
(print C::OtherFileClass::cOtherFileClassVar)
(print ::C::OtherFileClass::cOtherFileClassVar): New tests.
(ptype OtherFileClass, ptype ::C::OtherFileClass): Permit arbitrary
trailing content.
* gdb.cp/namespace1.cc (C::OtherFileClass::cOtherFileClassType)
(C::OtherFileClass::cOtherFileClassVar)
(C::OtherFileClass::cOtherFileClassVar_use, C::cOtherFileType)
(C::cOtherFileVar, C::cOtherFileVar_use): New.
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -578,11 +578,24 @@ cp_lookup_nested_type (struct type *parent_type,
nested_name,
block,
VAR_DOMAIN);
+ char *concatenated_name;
- if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF)
- return NULL;
- else
+ if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
return SYMBOL_TYPE (sym);
+
+ /* Now search all static file-level symbols. Not strictly correct,
+ but more useful than an error. We do not try to guess any imported
+ namespace as even the fully specified namespace seach is is already
+ not C++ compliant and more assumptions could make it too magic. */
+
+ concatenated_name = alloca (strlen (parent_name) + 2
+ + strlen (nested_name) + 1);
+ sprintf (concatenated_name, "%s::%s", parent_name, nested_name);
+ sym = lookup_static_symbol_aux (concatenated_name, VAR_DOMAIN);
+ if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+ return SYMBOL_TYPE (sym);
+
+ return NULL;
}
default:
internal_error (__FILE__, __LINE__,
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1054,7 +1054,6 @@ lookup_symbol_aux (const char *name, const struct block *block,
{
struct symbol *sym;
const struct language_defn *langdef;
- struct objfile *objfile;
/* Make sure we do something sensible with is_a_field_of_this, since
the callers that set this parameter to some non-null value will
@@ -1122,10 +1121,21 @@ lookup_symbol_aux (const char *name, const struct block *block,
return sym;
/* Now search all static file-level symbols. Not strictly correct,
- but more useful than an error. Do the symtabs first, then check
- the psymtabs. If a psymtab indicates the existence of the
- desired name as a file-level static, then do psymtab-to-symtab
- conversion on the fly and return the found symbol. */
+ but more useful than an error. */
+
+ return lookup_static_symbol_aux (name, domain);
+}
+
+/* Search all static file-level symbols for NAME from DOMAIN. Do the symtabs
+ first, then check the psymtabs. If a psymtab indicates the existence of the
+ desired name as a file-level static, then do psymtab-to-symtab conversion on
+ the fly and return the found symbol. */
+
+struct symbol *
+lookup_static_symbol_aux (const char *name, const domain_enum domain)
+{
+ struct objfile *objfile;
+ struct symbol *sym;
sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, domain);
if (sym != NULL)
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -886,6 +886,12 @@ extern struct symbol *lookup_symbol_aux_block (const char *name,
const struct block *block,
const domain_enum domain);
+/* Lookup a symbol only in the file static scope of all the objfiles. */
+
+struct symbol *lookup_static_symbol_aux (const char *name,
+ const domain_enum domain);
+
+
/* lookup a symbol by name, within a specified block */
extern struct symbol *lookup_block_symbol (const struct block *, const char *,
--- a/gdb/testsuite/gdb.cp/namespace.exp
+++ b/gdb/testsuite/gdb.cp/namespace.exp
@@ -165,6 +165,66 @@ gdb_test "print BBB::Class::xyzq" \
gdb_test "break BBB::Class::xyzq" \
"Breakpoint.*at $hex: file.*namespace.cc, line 68\\."
+# Tests accessing static elements in namespace of other file.
+
+gdb_test "whatis C::cOtherFileType" "type = short"
+gdb_test "whatis ::C::cOtherFileType" "type = short"
+gdb_test "whatis C::cOtherFileVar" "type = const C::cOtherFileType"
+setup_kfail "c++/11703" "*-*-*"
+gdb_test "whatis ::C::cOtherFileVar" "type = const C::cOtherFileType"
+gdb_test "print C::cOtherFileVar" "\\$\[0-9\].* = 319"
+setup_kfail "c++/11703" "*-*-*"
+gdb_test "print ::C::cOtherFileVar" "\\$\[0-9\].* = 319"
+
+if {[test_compiler_info {gcc-[0-3]-*}]
+ || [test_compiler_info {gcc-4-[0-4]-*}]} {
+ # The type in class is missing in older GCCs.
+ setup_xfail *-*-*
+}
+gdb_test "whatis C::OtherFileClass::cOtherFileClassType" "type = short"
+if {[test_compiler_info {gcc-[0-3]-*}]
+ || [test_compiler_info {gcc-4-[0-4]-*}]} {
+ # The type in class is missing in older GCCs.
+ setup_xfail *-*-*
+}
+gdb_test "whatis ::C::OtherFileClass::cOtherFileClassType" "type = short"
+
+set test "print C::OtherFileClass::cOtherFileClassVar"
+gdb_test_multiple $test $test {
+ -re "\\$\[0-9\].* = 318\r\n$gdb_prompt $" {
+ pass $test
+ }
+ -re "static field cOtherFileClassVar has been optimized out\r\n$gdb_prompt $" {
+ setup_kfail "c++/11702" "*-*-*"
+ fail $test
+ }
+}
+if {[test_compiler_info {gcc-[0-3]-*}]
+ || [test_compiler_info {gcc-4-[0-4]-*}]} {
+ # Older GCCs create unqualified DIE "cOtherFileClassVar" ignoring the
+ # namespace the same way GDB does.
+ setup_xfail *-*-*
+} else {
+ setup_kfail "c++/11703" "*-*-*"
+}
+set test "print ::C::OtherFileClass::cOtherFileClassVar"
+gdb_test_multiple $test $test {
+ -re "\\$\[0-9\].* = 318\r\n$gdb_prompt $" {
+ if {[test_compiler_info {gcc-[0-3]-*}]
+ || [test_compiler_info {gcc-4-[0-4]-*}]} {
+ # Older GCCs create unqualified DIE "cOtherFileClassVar" ignoring the
+ # namespace the same way GDB does.
+ xfail $test
+ } else {
+ pass $test
+ }
+ }
+ -re "$gdb_prompt $" {
+ setup_kfail "c++/11703" "*-*-*"
+ fail $test
+ }
+}
+
# Test to see if the appropriate namespaces are in scope when trying
# to print out stuff from within a function defined within a
# namespace.
@@ -201,8 +261,8 @@ gdb_test "ptype C::NestedClass" "No symbol \"NestedClass\" in namespace \"C::C\"
# Tests involving multiple files
gdb_test "print cOtherFile" "\\$\[0-9\].* = 316"
-gdb_test "ptype OtherFileClass" "type = (class C::OtherFileClass \{\r\n public:|struct C::OtherFileClass \{)\r\n int z;\r\n\}"
-gdb_test "ptype ::C::OtherFileClass" "type = class C::OtherFileClass \{\r\n public:\r\n int z;\r\n\}"
+gdb_test "ptype OtherFileClass" "type = (class C::OtherFileClass \{\r\n public:|struct C::OtherFileClass \{)\r\n int z;\r\n.*\}"
+gdb_test "ptype ::C::OtherFileClass" "type = class C::OtherFileClass \{\r\n public:\r\n int z;\r\n.*\}"
gdb_test "ptype C::OtherFileClass" "No symbol \"OtherFileClass\" in namespace \"C::C\"."
# Some anonymous namespace tests.
--- a/gdb/testsuite/gdb.cp/namespace1.cc
+++ b/gdb/testsuite/gdb.cp/namespace1.cc
@@ -21,7 +21,15 @@ namespace C
class OtherFileClass {
public:
int z;
+
+ typedef short cOtherFileClassType;
+ static const cOtherFileClassType cOtherFileClassVar = 318;
+ cOtherFileClassType cOtherFileClassVar_use ();
};
+ OtherFileClass::cOtherFileClassType OtherFileClass::cOtherFileClassVar_use ()
+ {
+ return cOtherFileClassVar;
+ }
namespace {
int cXOtherFile = 29;
@@ -35,6 +43,13 @@ namespace C
static OtherFileClass *c = new OtherFileClass();
c->z = cOtherFile + cXOtherFile;
}
+
+ typedef short cOtherFileType;
+ static const cOtherFileType cOtherFileVar = 319;
+ cOtherFileType cOtherFileVar_use ()
+ {
+ return cOtherFileVar;
+ }
}
namespace {
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3284,8 +3284,16 @@ value_maybe_namespace_elt (const struct type *curtype,
struct value *result;
sym = cp_lookup_symbol_namespace (namespace_name, name,
- get_selected_block (0),
- VAR_DOMAIN);
+ get_selected_block (0), VAR_DOMAIN);
+
+ if (sym == NULL)
+ {
+ char *concatenated_name = alloca (strlen (namespace_name) + 2
+ + strlen (name) + 1);
+
+ sprintf (concatenated_name, "%s::%s", namespace_name, name);
+ sym = lookup_static_symbol_aux (concatenated_name, VAR_DOMAIN);
+ }
if (sym == NULL)
return NULL;