[rfa] teach lookup_symbol about namespace scope

David Carlton
2003-04-24T01:25:36Z

This patch teaches lookup_symbol and friends about namespace scope and
about using directives. Basically, if you have a situation

namespace C {
namespace D {
void f()
{
// body of f
}
}
}

and you're in a breakpoint within 'f', then, when looking up a name
'x', you first look for C::D::x, then C::x, and finally x. Also, you
might have to apply using directives. (We currently only generate
using directives to tell us about anonymous namespaces.)

Some notes:

* This replaces the calls in lookup_symbol_aux to lookup a symbol in
the current file's static block and in all files' global blocks with
a call to lookup_symbol_aux_namespace_scope.

* That latter latter function, in turn, goes through all the
namespaces in scope, in the correct order, and tries to find the
symbol in each of them.

* It does that by calling a function lookup_symbol_namespace. This
function I've exported, even though it's only being used with
symtab.c, because it will be useful from other files in future
patches.

* lookup_symbol_namespace goes through all the using directives and
tries to apply them; if none of them work, it searches the current
namespace. It does that by calling 'lookup_symbol_file'.

* lookup_symbol_file is where the original calls to search the current
file's static block and all files' global blocks was moved to.
Except that it's a bit uglier than that: if we're looking for a
symbol within an anonymous namespace, we should only search the
current file's global block.

* Since I never got an answer about the fate of
lookup_symbol_aux_minsyms, I just deleted the bad part of that
function and commented out the rest. If there's a feeling that
that's bad, I can handle the situation slightly differently; also, I
can easily commit that part of the patch separately if desired.

* This is all safe in the non-C++ case: it reverts to the old behavior
in that situation, and the cost of the few extra function calls
involved will be swamped by the cost of actually doing the work of
looking up symbols.

I think that's about it, though I'm probably forgetting something.
This needs symtab approval, though obviously I'd appreciate it if
Daniel could look it over as well. Tested on GCC 3.2, DWARF 2,
i686-pc-linux-gnu; no new regressions. (And I've been using a version
of this for months on my branch, too.)

David Carlton
carlton@bactrian.org

2003-04-23 David Carlton <carlton@bactrian.org>

* symtab.h: Declare lookup_symbol_namespace.
* symtab.c: Include cp-support.h, gdb_assert.h.
(lookup_symbol_aux): Delete calls to lookup_symbol_aux_minsyms.
Delete 'static_block' variable.
Handle static and global search via
lookup_symbol_aux_namespace_scope.
(lookup_symbol_aux_local): Delete 'static_block' argument.
(lookup_symbol_aux_minsyms): Delete lookup by mangled name;
comment out rest of function.
(lookup_symbol_aux_namespace_scope): New.
(lookup_symbol_namespace, lookup_symbol_aux_file): Ditto.
* block.h: Declare block_scope, block_using, block_static_block.
* block.c (block_scope): New.
(block_using, block_static_block): Ditto.
* Makefile.in (symtab.o): Depend on cp_support_h and gdb_assert.
* config/djgpp/fnchange.lst: Add namespace1.cc.

2003-04-23 David Carlton <carlton@bactrian.org>

* gdb.c++/namespace.exp: Add namespace scope and anonymous
namespace tests.
Bump copyright date.
* gdb.c++/namespace.cc: Add anonymous namespace and namespace C
and everything within it.
(main): Call C::D::marker2.
* gdb.c++/namespace1.cc: New file.

Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.68
diff -u -p -r1.68 symtab.h
--- symtab.h 14 Apr 2003 19:55:27 -0000 1.68
+++ symtab.h 24 Apr 2003 00:46:53 -0000
@@ -1003,6 +1003,15 @@ extern struct symbol *lookup_symbol (con
const namespace_enum, int *,
struct symtab **);

+/* Lookup a symbol within a namespace. */
+
+extern struct symbol *lookup_symbol_namespace (const char *cp_namespace,
+ const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ namespace_enum gdb_namespace,
+ struct symtab **symtab);
+
/* lookup a symbol by name, within a specified block */

extern struct symbol *lookup_block_symbol (const struct block *, const char *,
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.101
diff -u -p -r1.101 symtab.c
--- symtab.c 14 Apr 2003 19:56:32 -0000 1.101
+++ symtab.c 24 Apr 2003 01:07:52 -0000
@@ -52,6 +52,8 @@
#include "gdb_stat.h"
#include <ctype.h>
#include "cp-abi.h"
+#include "cp-support.h"
+#include "gdb_assert.h"

/* Prototypes for local functions */

@@ -92,8 +94,7 @@ struct symbol *lookup_symbol_aux_local (
const char *mangled_name,
const struct block *block,
const namespace_enum namespace,
- struct symtab **symtab,
- const struct block **static_block);
+ struct symtab **symtab);

static
struct symbol *lookup_symbol_aux_block (const char *name,
@@ -116,12 +117,30 @@ struct symbol *lookup_symbol_aux_psymtab
const namespace_enum namespace,
struct symtab **symtab);

+#if 0
static
struct symbol *lookup_symbol_aux_minsyms (const char *name,
const char *mangled_name,
const namespace_enum namespace,
int *is_a_field_of_this,
struct symtab **symtab);
+#endif
+
+static
+struct symbol *lookup_symbol_aux_namespace_scope (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ namespace_enum namespace,
+ struct symtab **symtab,
+ const char *scope,
+ int scope_len);
+
+static struct symbol *lookup_symbol_aux_file (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const namespace_enum namespace,
+ struct symtab **symtab,
+ int anonymous_namespace);

static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr);

@@ -943,7 +962,7 @@ lookup_symbol_aux (const char *name, con
STATIC_BLOCK or GLOBAL_BLOCK. */

sym = lookup_symbol_aux_local (name, mangled_name, block, namespace,
- symtab, &static_block);
+ symtab);
if (sym != NULL)
return sym;

@@ -1009,65 +1028,12 @@ lookup_symbol_aux (const char *name, con
}
}

- /* If there's a static block to search, search it next. */
-
- /* NOTE: carlton/2002-12-05: There is a question as to whether or
- not it would be appropriate to search the current global block
- here as well. (That's what this code used to do before the
- is_a_field_of_this check was moved up.) On the one hand, it's
- redundant with the lookup_symbol_aux_symtabs search that happens
- next. On the other hand, if decode_line_1 is passed an argument
- like filename:var, then the user presumably wants 'var' to be
- searched for in filename. On the third hand, there shouldn't be
- multiple global variables all of which are named 'var', and it's
- not like decode_line_1 has ever restricted its search to only
- global variables in a single filename. All in all, only
- searching the static block here seems best: it's correct and it's
- cleanest. */
-
- /* NOTE: carlton/2002-12-05: There's also a possible performance
- issue here: if you usually search for global symbols in the
- current file, then it would be slightly better to search the
- current global block before searching all the symtabs. But there
- are other factors that have a much greater effect on performance
- than that one, so I don't think we should worry about that for
- now. */
-
- if (static_block != NULL)
- {
- sym = lookup_symbol_aux_block (name, mangled_name, static_block,
- namespace, symtab);
- if (sym != NULL)
- return sym;
- }
-
- /* Now search all global blocks. Do the symtab's first, then
- check the psymtab's. If a psymtab indicates the existence
- of the desired name as a global, then do psymtab-to-symtab
- conversion on the fly and return the found symbol. */
-
- sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, mangled_name,
- namespace, symtab);
- if (sym != NULL)
- return sym;
-
-#ifndef HPUXHPPA
-
- /* Check for the possibility of the symbol being a function or
- a mangled variable that is stored in one of the minimal symbol tables.
- Eventually, all global symbols might be resolved in this way. */
-
- sym = lookup_symbol_aux_minsyms (name, mangled_name,
- namespace, is_a_field_of_this,
- symtab);
-
- if (sym != NULL)
- return sym;
-
-#endif
+ /* Now search this block's static block, and all the global blocks.
+ In the C++ case, do lookup in namespace scope. */

- sym = lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, mangled_name,
- namespace, symtab);
+ sym = lookup_symbol_aux_namespace_scope (name, mangled_name, block,
+ namespace, symtab,
+ block_scope (block), 0);
if (sym != NULL)
return sym;

@@ -1087,60 +1053,29 @@ lookup_symbol_aux (const char *name, con
if (sym != NULL)
return sym;

-#ifdef HPUXHPPA
-
- /* Check for the possibility of the symbol being a function or
- a global variable that is stored in one of the minimal symbol tables.
- The "minimal symbol table" is built from linker-supplied info.
-
- RT: I moved this check to last, after the complete search of
- the global (p)symtab's and static (p)symtab's. For HP-generated
- symbol tables, this check was causing a premature exit from
- lookup_symbol with NULL return, and thus messing up symbol lookups
- of things like "c::f". It seems to me a check of the minimal
- symbol table ought to be a last resort in any case. I'm vaguely
- worried about the comment below which talks about FORTRAN routines "foo_"
- though... is it saying we need to do the "minsym" check before
- the static check in this case?
- */
-
-
- sym = lookup_symbol_aux_minsyms (name, mangled_name,
- namespace, is_a_field_of_this,
- symtab);
-
- if (sym != NULL)
- return sym;
-
-#endif
-
if (symtab != NULL)
*symtab = NULL;
return NULL;
}

/* Check to see if the symbol is defined in BLOCK or its superiors.
- Don't search STATIC_BLOCK or GLOBAL_BLOCK. If we don't find a
- match, store the address of STATIC_BLOCK in static_block. */
+ Don't search STATIC_BLOCK or GLOBAL_BLOCK. */

static struct symbol *
lookup_symbol_aux_local (const char *name, const char *mangled_name,
const struct block *block,
const namespace_enum namespace,
- struct symtab **symtab,
- const struct block **static_block)
+ struct symtab **symtab)
{
struct symbol *sym;
-
- /* Check if either no block is specified or it's a global block. */
+ const struct block *static_block = block_static_block (block);

- if (block == NULL || BLOCK_SUPERBLOCK (block) == NULL)
- {
- *static_block = NULL;
- return NULL;
- }
+ /* Either no block is specified or it's a global block. */
+
+ if (static_block == NULL)
+ return NULL;

- while (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) != NULL)
+ while (block != static_block)
{
sym = lookup_symbol_aux_block (name, mangled_name, block, namespace,
symtab);
@@ -1149,9 +1084,8 @@ lookup_symbol_aux_local (const char *nam
block = BLOCK_SUPERBLOCK (block);
}

- /* We've reached the static block. */
+ /* We've reached the static block without finding a result. */

- *static_block = block;
return NULL;
}

@@ -1290,6 +1224,7 @@ lookup_symbol_aux_psymtabs (int block_in
return NULL;
}

+#if 0
/* Check for the possibility of the symbol being a function or a
mangled variable that is stored in one of the minimal symbol
tables. Eventually, all global symbols might be resolved in this
@@ -1303,6 +1238,11 @@ lookup_symbol_aux_psymtabs (int block_in
some additional conditions held as well, and it caused problems
with HP-generated symbol tables. */

+/* NOTE: carlton/2003-04-23: This function was once used as part of
+ lookup_symbol. It is currently unnecessary for correctness
+ reasons, however, and using it doesn't seem to be any faster than
+ using lookup_symbol_aux_psymtabs, so I'm commenting it out. */
+
static struct symbol *
lookup_symbol_aux_minsyms (const char *name,
const char *mangled_name,
@@ -1403,20 +1343,162 @@ lookup_symbol_aux_minsyms (const char *n
*symtab = s;
return fixup_symbol_section (sym, s->objfile);
}
- else if (MSYMBOL_TYPE (msymbol) != mst_text
- && MSYMBOL_TYPE (msymbol) != mst_file_text
- && !STREQ (name, DEPRECATED_SYMBOL_NAME (msymbol)))
- {
- /* This is a mangled variable, look it up by its
- mangled name. */
- return lookup_symbol_aux (DEPRECATED_SYMBOL_NAME (msymbol), mangled_name,
- NULL, namespace, is_a_field_of_this,
- symtab);
- }
}
}

return NULL;
+}
+#endif /* 0 */
+
+/* Lookup NAME at namespace scope (or, in C terms, in static and
+ global variables). SCOPE is the namespace that the current
+ function is defined within; only consider namespaces whose length
+ is at least SCOPE_LEN. (This is to make the recursion easier.) */
+
+static struct symbol *
+lookup_symbol_aux_namespace_scope (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ namespace_enum namespace,
+ struct symtab **symtab,
+ const char *scope,
+ int scope_len)
+{
+ char *cp_namespace;
+
+ if (scope[scope_len] != '\0')
+ {
+ struct symbol *sym;
+ int new_scope_len = scope_len;
+
+ /* If the current scope is followed by "::", skip past that. */
+ if (new_scope_len != 0)
+ {
+ gdb_assert (scope[new_scope_len] == ':');
+ new_scope_len += 2;
+ }
+ new_scope_len += cp_find_first_component (scope + new_scope_len);
+ sym = lookup_symbol_aux_namespace_scope (name, linkage_name, block,
+ namespace, symtab,
+ scope, new_scope_len);
+ if (sym != NULL)
+ return sym;
+ }
+
+ cp_namespace = alloca (scope_len + 1);
+ strncpy (cp_namespace, scope, scope_len);
+ cp_namespace[scope_len] = '\0';
+ return lookup_symbol_namespace (cp_namespace, name, linkage_name,
+ block, namespace, symtab);
+}
+
+/* Look up NAME in the C++ namespace CP_NAMESPACE, applying the using
+ directives that are active in BLOCK. Otherwise, arguments are as
+ in lookup_symbol_aux. */
+
+struct symbol *
+lookup_symbol_namespace (const char *cp_namespace,
+ const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ namespace_enum gdb_namespace,
+ struct symtab **symtab)
+{
+ const struct using_direct *current;
+ struct symbol *sym;
+
+ /* First, go through the using directives. If any of them add new
+ names to the namespace we're searching in, see if we can find a
+ match by applying them. */
+
+ for (current = block_using (block);
+ current != NULL;
+ current = current->next)
+ {
+ if (strcmp (cp_namespace, current->outer) == 0)
+ {
+ sym = lookup_symbol_namespace (current->inner,
+ name,
+ linkage_name,
+ block,
+ gdb_namespace,
+ symtab);
+ if (sym != NULL)
+ return sym;
+ }
+ }
+
+ /* We didn't find anything by applying any of the using directives
+ that are still applicable; so let's see if we've got a match
+ using the current namespace. */
+
+ if (cp_namespace[0] == '\0')
+ {
+ return lookup_symbol_aux_file (name, linkage_name, block,
+ gdb_namespace, symtab,
+ 0);
+ }
+ else
+ {
+ char *concatenated_name
+ = alloca (strlen (cp_namespace) + 2 + strlen (name) + 1);
+ strcpy (concatenated_name, cp_namespace);
+ strcat (concatenated_name, "::");
+ strcat (concatenated_name, name);
+ sym = lookup_symbol_aux_file (concatenated_name, linkage_name,
+ block, gdb_namespace, symtab,
+ cp_is_anonymous (cp_namespace));
+ return sym;
+ }
+}
+
+/* Look up NAME in BLOCK's static block and in global blocks. If
+ ANONYMOUS_NAMESPACE is nonzero, don't look in other files' global
+ blocks, just in the one belonging to this file. */
+
+static struct symbol *
+lookup_symbol_aux_file (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const namespace_enum namespace,
+ struct symtab **symtab,
+ int anonymous_namespace)
+{
+ struct symbol *sym = NULL;
+ const struct block *static_block = block_static_block (block);
+
+ if (static_block != NULL)
+ {
+ sym = lookup_symbol_aux_block (name, linkage_name, static_block,
+ namespace, symtab);
+ if (sym != NULL)
+ return sym;
+ }
+
+ if (anonymous_namespace)
+ {
+ const struct block *global_block = NULL;
+ if (static_block != NULL)
+ global_block = BLOCK_SUPERBLOCK (static_block);
+ else if (block != NULL)
+ global_block = block;
+
+ if (global_block != NULL)
+ return lookup_symbol_aux_block (name, linkage_name, global_block,
+ namespace, symtab);
+ else
+ return NULL;
+ }
+ else
+ {
+ sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name,
+ namespace, symtab);
+ if (sym != NULL)
+ return sym;
+ else
+ return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name,
+ namespace, symtab);
+ }
}

/* Look, in partial_symtab PST, for symbol whose natural name is NAME.
Index: block.h
===================================================================
RCS file: /cvs/src/src/gdb/block.h,v
retrieving revision 1.3
diff -u -p -r1.3 block.h
--- block.h 15 Apr 2003 23:07:11 -0000 1.3
+++ block.h 24 Apr 2003 00:43:48 -0000
@@ -200,11 +200,17 @@ extern struct block *block_for_pc (CORE_

extern struct block *block_for_pc_sect (CORE_ADDR, asection *);

+extern const char *block_scope (const struct block *block);
+
extern void block_set_scope (struct block *block, const char *scope,
struct obstack *obstack);

+extern struct using_direct *block_using (const struct block *block);
+
extern void block_set_using (struct block *block,
struct using_direct *using,
struct obstack *obstack);
+
+extern const struct block *block_static_block (const struct block *block);

#endif /* BLOCK_H */
Index: block.c
===================================================================
RCS file: /cvs/src/src/gdb/block.c,v
retrieving revision 1.3
diff -u -p -r1.3 block.c
--- block.c 15 Apr 2003 23:07:11 -0000 1.3
+++ block.c 24 Apr 2003 00:46:01 -0000
@@ -155,8 +155,25 @@ block_for_pc (register CORE_ADDR pc)
return block_for_pc_sect (pc, find_pc_mapped_section (pc));
}

-/* Now come some functions designed to deal with C++ namespace
- issues. */
+/* Now come some functions designed to deal with C++ namespace issues.
+ The accessors are safe to use even in the non-C++ case. */
+
+/* This returns the namespace that BLOCK is enclosed in, or "" if it
+ isn't enclosed in a namespace at all. This travels the chain of
+ superblocks looking for a scope, if necessary. */
+
+const char *
+block_scope (const struct block *block)
+{
+ for (; block != NULL; block = BLOCK_SUPERBLOCK (block))
+ {
+ if (BLOCK_NAMESPACE (block) != NULL
+ && BLOCK_NAMESPACE (block)->scope != NULL)
+ return BLOCK_NAMESPACE (block)->scope;
+ }
+
+ return "";
+}

/* Set BLOCK's scope member to SCOPE; if needed, allocate memory via
OBSTACK. (It won't make a copy of SCOPE, however, so that already
@@ -171,6 +188,27 @@ block_set_scope (struct block *block, co
BLOCK_NAMESPACE (block)->scope = scope;
}

+/* This returns the first using directives associated to BLOCK, if
+ any. */
+
+/* FIXME: carlton/2003-04-23: This uses the fact that we currently
+ only have using directives in static blocks, because we only
+ generate using directives from anonymous namespaces. Eventually,
+ when we support using directives everywhere, we'll want to replace
+ this by some iterator functions. */
+
+struct using_direct *
+block_using (const struct block *block)
+{
+ const struct block *static_block = block_static_block (block);
+
+ if (static_block == NULL
+ || BLOCK_NAMESPACE (static_block) == NULL)
+ return NULL;
+ else
+ return BLOCK_NAMESPACE (static_block)->using;
+}
+
/* Set BLOCK's using member to USING; if needed, allocate memory via
OBSTACK. (It won't make a copy of USING, however, so that already
has to be allocated correctly.) */
@@ -198,4 +236,19 @@ block_initialize_namespace (struct block
BLOCK_NAMESPACE (block)->scope = NULL;
BLOCK_NAMESPACE (block)->using = NULL;
}
+}
+
+/* Return the static block associated to BLOCK. Return NULL if block
+ is NULL or if block is a global block. */
+
+const struct block *
+block_static_block (const struct block *block)
+{
+ if (block == NULL || BLOCK_SUPERBLOCK (block) == NULL)
+ return NULL;
+
+ while (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) != NULL)
+ block = BLOCK_SUPERBLOCK (block);
+
+ return block;
}
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.365
diff -u -p -r1.365 Makefile.in
--- Makefile.in 21 Apr 2003 16:48:36 -0000 1.365
+++ Makefile.in 24 Apr 2003 00:43:20 -0000
@@ -2275,7 +2275,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_h)
$(gdbcmd_h) $(call_cmds_h) $(gdb_regex_h) $(expression_h) \
$(language_h) $(demangle_h) $(inferior_h) $(linespec_h) \
$(filenames_h) $(gdb_obstack_h) $(gdb_string_h) $(gdb_stat_h) \
- $(cp_abi_h) $(source_h) $(block_h)
+ $(cp_abi_h) $(source_h) $(block_h) $(cp_support_h) $(gdb_assert_h)
target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
$(gdb_wait_h) $(dcache_h) $(regcache_h)
Index: fnchange.lst
===================================================================
RCS file: /cvs/src/src/gdb/config/djgpp/fnchange.lst,v
retrieving revision 1.46
diff -u -p -r1.46 fnchange.lst
--- fnchange.lst 5 Feb 2003 06:41:15 -0000 1.46
+++ fnchange.lst 24 Apr 2003 01:08:12 -0000
@@ -243,6 +243,7 @@
@V@/gdb/testsuite/gdb.c++/misc.cc @V@/gdb/testsuite/gdb.cxx/misc.cc
@V@/gdb/testsuite/gdb.c++/misc.exp @V@/gdb/testsuite/gdb.cxx/misc.exp
@V@/gdb/testsuite/gdb.c++/namespace.cc @V@/gdb/testsuite/gdb.cxx/namespace.cc
+@V@/gdb/testsuite/gdb.c++/namespace1.cc @V@/gdb/testsuite/gdb.cxx/namesp1.cc
@V@/gdb/testsuite/gdb.c++/namespace.exp @V@/gdb/testsuite/gdb.cxx/namespace.exp
@V@/gdb/testsuite/gdb.c++/overload.cc @V@/gdb/testsuite/gdb.cxx/overload.cc
@V@/gdb/testsuite/gdb.c++/overload.exp @V@/gdb/testsuite/gdb.cxx/overload.exp
Index: namespace.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/namespace.exp,v
retrieving revision 1.12
diff -u -p -r1.12 namespace.exp
--- namespace.exp 10 Jan 2002 20:46:16 -0000 1.12
+++ namespace.exp 24 Apr 2003 01:05:04 -0000
@@ -1,4 +1,4 @@
-# Copyright 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+# Copyright 1997, 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -186,3 +186,27 @@ gdb_expect {
timeout { fail "(timeout) break BBB::Class::xyzq" }
}

+# Test to see if the appropriate namespaces are in scope when trying
+# to print out stuff from within a function defined within a
+# namespace.
+
+if ![runto "C::D::marker2"] then {
+ perror "couldn't run to marker2"
+ continue
+}
+
+gdb_test "print c" "\\$\[0-9\].* = 1"
+gdb_test "print cc" "No symbol \"cc\" in current context."
+gdb_test "print 'C::cc'" "\\$\[0-9\].* = 2"
+gdb_test "print cd" "\\$\[0-9\].* = 3"
+gdb_test "print 'E::cde'" "\\$\[0-9\].* = 5"
+gdb_test "print shadow" "\\$\[0-9\].* = 13"
+
+# Some anonymous namespace tests.
+
+gdb_test "print cX" "\\$\[0-9\].* = 6"
+gdb_test "print 'F::cXf'" "\\$\[0-9\].* = 7"
+gdb_test "print X" "\\$\[0-9\].* = 9"
+gdb_test "print 'G::Xg'" "\\$\[0-9\].* = 10"
+gdb_test "print cXOtherFile" "No symbol \"cXOtherFile\" in current context."
+gdb_test "print XOtherFile" "No symbol \"XOtherFile\" in current context."
Index: namespace.cc
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/namespace.cc,v
retrieving revision 1.1
diff -u -p -r1.1 namespace.cc
--- namespace.cc 12 Jun 2000 01:31:41 -0000 1.1
+++ namespace.cc 24 Apr 2003 01:04:52 -0000
@@ -68,6 +68,70 @@ void marker1(void)
return;
}

+namespace
+{
+ int X = 9;
+
+ namespace G
+ {
+ int Xg = 10;
+ }
+}
+
+namespace C
+{
+ int c = 1;
+ int shadow = 12;
+
+ namespace
+ {
+ int cX = 6;
+
+ namespace F
+ {
+ int cXf = 7;
+ }
+ }
+
+ namespace C
+ {
+ int cc = 2;
+ }
+
+ namespace D
+ {
+ int cd = 3;
+ int shadow = 13;
+
+ namespace E
+ {
+ int cde = 5;
+ }
+
+ void marker2 (void)
+ {
+ // NOTE: carlton/2003-04-23: I'm listing the expressions that I
+ // plan to have GDB try to print out, just to make sure that the
+ // compiler and I agree which ones should be legal! It's easy
+ // to screw up when testing the boundaries of namespace stuff.
+ c;
+ //cc;
+ C::cc;
+ cd;
+ E::cde;
+ shadow;
+ cX;
+ F::cXf;
+ X;
+ G::Xg;
+ //cXOtherFile;
+ //XOtherFile;
+
+ return;
+ }
+
+ }
+}

int main ()
{
@@ -95,9 +159,5 @@ int main ()

marker1();

+ C::D::marker2 ();
}
-
-
-
-
-
--- /dev/null 2002-08-30 16:31:37.000000000 -0700
+++ namespace1.cc 2003-04-23 18:04:04.000000000 -0700
@@ -0,0 +1,29 @@
+# Copyright 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+namespace C
+{
+ namespace {
+ int cXOtherFile = 29;
+ };
+}
+
+namespace {
+ int XOtherFile = 317;
+}