This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [rfa] namespace scope, take 2
- From: David Carlton <carlton at math dot stanford dot edu>
- To: Daniel Jacobowitz <drow at mvista dot com>
- Cc: gdb-patches at sources dot redhat dot com, Elena Zannoni <ezannoni at redhat dot com>
- Date: 19 May 2003 20:57:23 -0700
- Subject: Re: [rfa] namespace scope, take 2
- References: <m3addjyicq.fsf@papaya.bactrian.org><20030519144508.GA25940@nevyn.them.org>
On Mon, 19 May 2003 10:45:08 -0400, Daniel Jacobowitz <drow@mvista.com> said:
> Just a couple small comments. Most of it looks good.
Thanks, checked in with your and Elena's changes. Revised
cp-namespace.c below.
David Carlton
carlton@math.stanford.edu
Index: cp-namespace.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-namespace.c,v
retrieving revision 1.1
diff -u -p -r1.1 cp-namespace.c
--- cp-namespace.c 15 Apr 2003 23:07:11 -0000 1.1
+++ cp-namespace.c 20 May 2003 03:55:44 -0000
@@ -1,7 +1,7 @@
/* Helper routines for C++ support in GDB.
Copyright 2003 Free Software Foundation, Inc.
- Contributed by David Carlton.
+ Contributed by David Carlton and by Kealia, Inc.
This file is part of GDB.
@@ -52,6 +52,21 @@ static struct using_direct *cp_add_using
static struct using_direct *cp_copy_usings (struct using_direct *using,
struct obstack *obstack);
+static struct symbol *lookup_namespace_scope (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain,
+ struct symtab **symtab,
+ const char *scope,
+ int scope_len);
+
+static struct symbol *lookup_symbol_file (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain,
+ struct symtab **symtab,
+ int anonymous_namespace);
+
/* Set up support for dealing with C++ namespace info in the current
symtab. */
@@ -262,5 +277,179 @@ cp_copy_usings (struct using_direct *usi
xfree (using);
return retval;
+ }
+}
+
+/* The C++-specific version of name lookup for static and global
+ names. This makes sure that names get looked for in all namespaces
+ that are in scope. NAME is the natural name of the symbol that
+ we're looking for, LINKAGE_NAME (which is optional) is its linkage
+ name, BLOCK is the block that we're searching within, DOMAIN says
+ what kind of symbols we're looking for, and if SYMTAB is non-NULL,
+ we should store the symtab where we found the symbol in it. */
+
+struct symbol *
+cp_lookup_symbol_nonlocal (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain,
+ struct symtab **symtab)
+{
+ return lookup_namespace_scope (name, linkage_name, block, domain,
+ symtab, block_scope (block), 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. Other arguments are as in
+ cp_lookup_symbol_nonlocal.
+
+ For example, if we're within a function A::B::f and looking for a
+ symbol f, this will get called with NAME = "f", SCOPE = "A::B", and
+ SCOPE_LEN = 0. It then calls itself with NAME and SCOPE the same,
+ but with SCOPE_LEN = 1. And then it calls itself with NAME and
+ SCOPE the same, but with SCOPE_LEN = 4. This third call looks for
+ "A::B::x"; if it doesn't find it, then the second call looks for
+ "A::x", and if that call fails, then the first call looks for
+ "x". */
+
+static struct symbol *
+lookup_namespace_scope (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain,
+ struct symtab **symtab,
+ const char *scope,
+ int scope_len)
+{
+ char *namespace;
+
+ if (scope[scope_len] != '\0')
+ {
+ /* Recursively search for names in child namespaces first. */
+
+ 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_namespace_scope (name, linkage_name, block,
+ domain, symtab,
+ scope, new_scope_len);
+ if (sym != NULL)
+ return sym;
+ }
+
+ /* Okay, we didn't find a match in our children, so look for the
+ name in the current namespace. */
+
+ namespace = alloca (scope_len + 1);
+ strncpy (namespace, scope, scope_len);
+ namespace[scope_len] = '\0';
+ return cp_lookup_symbol_namespace (namespace, name, linkage_name,
+ block, domain, symtab);
+}
+
+/* Look up NAME in the C++ namespace NAMESPACE, applying the using
+ directives that are active in BLOCK. Other arguments are as in
+ cp_lookup_symbol_nonlocal. */
+
+struct symbol *
+cp_lookup_symbol_namespace (const char *namespace,
+ const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain,
+ 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 (namespace, current->outer) == 0)
+ {
+ sym = cp_lookup_symbol_namespace (current->inner,
+ name,
+ linkage_name,
+ block,
+ domain,
+ 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 (namespace[0] == '\0')
+ {
+ return lookup_symbol_file (name, linkage_name, block,
+ domain, symtab, 0);
+ }
+ else
+ {
+ char *concatenated_name
+ = alloca (strlen (namespace) + 2 + strlen (name) + 1);
+ strcpy (concatenated_name, namespace);
+ strcat (concatenated_name, "::");
+ strcat (concatenated_name, name);
+ sym = lookup_symbol_file (concatenated_name, linkage_name,
+ block, domain, symtab,
+ cp_is_anonymous (namespace));
+ return sym;
+ }
+}
+
+/* Look up NAME in BLOCK's static block and in global blocks. If
+ ANONYMOUS_NAMESPACE is nonzero, the symbol in question is located
+ within an anonymous namespace. Other arguments are as in
+ cp_lookup_symbol_nonlocal. */
+
+static struct symbol *
+lookup_symbol_file (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain,
+ struct symtab **symtab,
+ int anonymous_namespace)
+{
+ struct symbol *sym = NULL;
+
+ sym = lookup_symbol_static (name, linkage_name, block, domain, symtab);
+ if (sym != NULL)
+ return sym;
+
+ if (anonymous_namespace)
+ {
+ /* Symbols defined in anonymous namespaces have external linkage
+ but should be treated as local to a single file nonetheless.
+ So we only search the current file's global block. */
+
+ const struct block *global_block = block_global_block (block);
+
+ if (global_block != NULL)
+ return lookup_symbol_aux_block (name, linkage_name, global_block,
+ domain, symtab);
+ else
+ return NULL;
+ }
+ else
+ {
+ return lookup_symbol_global (name, linkage_name, domain, symtab);
}
}