From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26466 invoked by alias); 20 May 2003 03:57:32 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 26435 invoked from network); 20 May 2003 03:57:31 -0000 Received: from unknown (HELO jackfruit.Stanford.EDU) (171.64.38.136) by sources.redhat.com with SMTP; 20 May 2003 03:57:31 -0000 Received: (from carlton@localhost) by jackfruit.Stanford.EDU (8.11.6/8.11.6) id h4K3vOH29051; Mon, 19 May 2003 20:57:24 -0700 X-Authentication-Warning: jackfruit.Stanford.EDU: carlton set sender to carlton@math.stanford.edu using -f To: Daniel Jacobowitz Cc: gdb-patches@sources.redhat.com, Elena Zannoni Subject: Re: [rfa] namespace scope, take 2 References: <20030519144508.GA25940@nevyn.them.org> From: David Carlton Date: Tue, 20 May 2003 03:57:00 -0000 In-Reply-To: <20030519144508.GA25940@nevyn.them.org> Message-ID: User-Agent: Gnus/5.0808 (Gnus v5.8.8) XEmacs/21.4 (Common Lisp) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2003-05/txt/msg00356.txt.bz2 On Mon, 19 May 2003 10:45:08 -0400, Daniel Jacobowitz 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); } }