From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16627 invoked by alias); 10 Apr 2002 01:35:56 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 16398 invoked from network); 10 Apr 2002 01:35:54 -0000 Received: from unknown (HELO zwingli.cygnus.com) (208.245.165.35) by sources.redhat.com with SMTP; 10 Apr 2002 01:35:54 -0000 Received: by zwingli.cygnus.com (Postfix, from userid 442) id 57C4C5EA11; Tue, 9 Apr 2002 20:35:53 -0500 (EST) To: Daniel Jacobowitz Cc: gdb@sources.redhat.com, Benjamin Kosnik , Daniel Berlin Subject: Re: C++ nested classes, namespaces, structs, and compound statements References: <20020406044204.245E45EA11@zwingli.cygnus.com> <20020406013408.A4570@nevyn.them.org> <20020408215921.B14098@nevyn.them.org> From: Jim Blandy Date: Tue, 09 Apr 2002 18:35:00 -0000 In-Reply-To: <20020408215921.B14098@nevyn.them.org> Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.1 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2002-04/txt/msg00145.txt.bz2 Ah, this is exactly the kind of debate I was looking for. :) Daniel Jacobowitz writes: > But let me put my cynic's cap on for a moment and point out some > problems. I'd love to see us just decide to overcome them all, and I > think it's viable, but we need to make sure we consider them first. > > The "incremental change" Problem This I especially suck at. So folks, please insist on getting an answer you're really comfortable with. Here's one way we could approach it: - First, we could simply replace the `nsyms' and `syms' members of `struct block' with a reference to our opaque `environment' object. There isn't that much code which works on those directly, so this wouldn't be too bad. - Next, we could replace the static and global blocks with `environment' objects, too. At this point, our environment object would be known to work. *ahem* - Make accessing a symbol's name go through an accessor function. It goes through a macro already, but we'd have to make sure it *always* goes through the macro. (Renaming the structure member and tweaking the macro accordingly would help us find code which doesn't go through the macro.) - Then we could go through an intermediate phase where things worked like this: a) The symbol table stores names either way: with an explicit namespace tree, or with qualified names sitting directly in the symbol table. (When I say "namespace", please understand that to also include classes, etc.) Any given symbol is stored only one way or the other, but any given symbol table can hold a mix of symbols in each form. Symbols stored in the explicit tree would have a `fully_qualified_name' field, so symtab clients expecting to see fully qualified names would still get them. b) The object representing a namespace keeps around the prefix it corresponds to (`std::' or `A::B::' or whatever), so that lookups of single name components relative to that namespace can find entries stored in either form. c) For backwards compatibility, the symbol lookup function would check for `::' in symbol names, and do a component-by-component lookup. Then, we could gradually do the following (some of these are interdependent, some not): - Change symbol table clients to call a function to print a symbol's qualified name relative to the current scope, rather than expecting to see a fully qualified name in the symbol structure itself. This would make b) unnecessary. - Change symbol table clients to do lookups one component at a time, making c) unnecessary. - Change symbol table readers to build explicit namespace trees, rather than dumping qualified names into the symbol table. This would make a) unnecessary. Now we've got symbol lookups switched over. Given the new representation, we can implement namespaces in a straightforward way. But what about structs? I don't have enough of a grasp on how data members, member functions, static members, etc. really work now to say how we'd switch struct types over to the new representation, but it seems like the same general approach should work: - Gradually replace code which manipulates the type structures directly with simple accessor functions, until the type can be made opaque. - Switch to an intermediate representation which allows both the old and the new representations, mixed. - Migrate clients and producers over to the newer interfaces. This is now a set of independent changes, that can be done in any order. - Once the producers are all creating data in the new style, remove support for it. Now you've got your new data structure, used as an opaque datatype. I feel like we're planning a construction project like Boston's Big Dig or something: everything's got to keep running while we do the work, and things will get pretty ugly in there for a while, but we hope (if our funding doesn't run out) that in the end it'll all be beautiful.