From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14284 invoked by alias); 19 Feb 2003 21:21:38 -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 14235 invoked from network); 19 Feb 2003 21:21:35 -0000 Received: from unknown (HELO zenia.red-bean.com) (66.244.67.22) by 172.16.49.205 with SMTP; 19 Feb 2003 21:21:35 -0000 Received: from zenia.red-bean.com (localhost.localdomain [127.0.0.1]) by zenia.red-bean.com (8.12.5/8.12.5) with ESMTP id h1JLEv8A030031; Wed, 19 Feb 2003 16:14:57 -0500 Received: (from jimb@localhost) by zenia.red-bean.com (8.12.5/8.12.5/Submit) id h1JLEuQg030027; Wed, 19 Feb 2003 16:14:56 -0500 To: David Carlton Cc: gdb-patches@sources.redhat.com, Elena Zannoni Subject: Re: [rfc] block.{h,c} References: From: Jim Blandy Date: Wed, 19 Feb 2003 21:21:00 -0000 In-Reply-To: Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2003-02/txt/msg00444.txt.bz2 I think it's a great idea. David Carlton writes: > I'd like to move 'struct block' out of symtab.h into a new file > block.h, and creating a new file block.c with block-specific > functions. Doing so would help lessen compilation dependencies, which > is important for people like me with slow computers: right now > symtab.h is included by around 140 files, while the resulting block.h > would only be included by around 40 or so. Basically, my code > organization philosophy says that you should only define two different > structures in the same include file if they are very closely linked > (e.g. if code that refers one would almost always refer to the other); > symtab.h doesn't pass that test. For example, there's no particular > reason why code using 'struct block' would be particluarly like to use > 'struct minimal_symbol', or vice-versa. > > I don't feel _too_ strongly about this; on the other hand, I can't see > any reason not to make this change other than inertia. (I guess that, > the more include files there are, the more possibility there is that > Makefile.in could get out of sync; that's not a good reason, though, > and maybe the ARI could check for that?) > > > What I'd propose putting in block.h are: > > * The definition of struct block. > > * Accessor macros for struct block. > > * The definition of struct blockvector. > > * Accessor macros for struct blockvector, and block number macros. > > * The following function declarations, whose definitions would be > moved to block.c: > > extern struct symbol *block_function (const struct block *); > extern int contained_in (const struct block *, const struct block *); > > Also, I'll soon want to add the following functions, which would all > be natural candidates for block.{c,h}: > > extern struct using_direct_node *block_using (const struct block *); > > extern struct using_direct_node *block_all_usings (const struct block *block); > > extern void block_set_using (struct block *block, > struct using_direct_node *using, > struct obstack *obstack); > > extern const char *block_scope (const struct block *block); > > extern void block_set_scope (struct block *block, const char *scope, > struct obstack *obstack); > > extern const struct block *block_static_block (const struct block *block); > > struct block_using_iterator > { > const struct block *current_block; > const struct using_direct_node *next_node; > }; > > extern struct > using_direct *block_using_iterator_first (const struct block *block, > struct block_using_iterator > *iterator); > > extern struct > using_direct *block_using_iterator_next (struct block_using_iterator > *iterator); > > extern struct block *allocate_block (struct obstack *obstack); > > > One could argue that all of these but block_static_block and > allocate_block could perhaps go in cp_support.{h,c} instead. I'd > rather have them in block.{h,c}, though. (Though probably > cp_support.{h,c} would be a better place for them than symtab.{h,c}.) > > I'll submit a formal RFA if the symtab maintainers are receptive to > the idea. If I could get feedback on this quickly, I'd appreciate it: > my first namespace patch will modify struct block (and will add many > of the aforementioned functions), so if block.h is going to be > created, I'd much rather have that done before my first namespace > patch. > > I'll include block.h from my branch after my signature; note, however, > that it has some unrelated differences from the relevant sections of > symtab.h on mainline CVS. (That's for a future RFC!) Still, it'll > give you an idea as to what block.h might look like. > > David Carlton > carlton@math.stanford.edu > > /* Block definitions for GDB. > Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, > 1997, 1998, 1999, 2000, 2001, 2002 > Free Software Foundation, Inc. > > This file is part of GDB. > > 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. */ > > /* All of the name-scope contours of the program > are represented by `struct block' objects. > All of these objects are pointed to by the blockvector. > > Each block represents one name scope. > Each lexical context has its own block. > > The blockvector begins with some special blocks. > The GLOBAL_BLOCK contains all the symbols defined in this compilation > whose scope is the entire program linked together. > The STATIC_BLOCK contains all the symbols whose scope is the > entire compilation excluding other separate compilations. > Blocks starting with the FIRST_LOCAL_BLOCK are not special. > > Each block records a range of core addresses for the code that > is in the scope of the block. The STATIC_BLOCK and GLOBAL_BLOCK > give, for the range of code, the entire range of code produced > by the compilation that the symbol segment belongs to. > > The blocks appear in the blockvector > in order of increasing starting-address, > and, within that, in order of decreasing ending-address. > > This implies that within the body of one function > the blocks appear in the order of a depth-first tree walk. */ > > /* Opaque declarations. */ > > struct symbol; > struct dictionary; > struct namespace_info; > struct using_direct_node; > struct obstack; > > struct block > { > > /* Addresses in the executable code that are in this block. */ > > CORE_ADDR startaddr; > CORE_ADDR endaddr; > > /* The symbol that names this block, if the block is the body of a > function; otherwise, zero. */ > > struct symbol *function; > > /* The `struct block' for the containing block, or 0 if none. > > The superblock of a top-level local block (i.e. a function in the > case of C) is the STATIC_BLOCK. The superblock of the > STATIC_BLOCK is the GLOBAL_BLOCK. */ > > struct block *superblock; > > /* This is used to store the symbols in the block. */ > > struct dictionary *dict; > > /* Used for language-specific info. */ > > union > { > struct > { > /* Contains information about namespace-related info relevant to > this block: using directives and the current namespace > scope. */ > > struct namespace_info *namespace; > } > cplus_specific; > } > language_specific; > > /* Version of GCC used to compile the function corresponding > to this block, or 0 if not compiled with GCC. When possible, > GCC should be compatible with the native compiler, or if that > is not feasible, the differences should be fixed during symbol > reading. As of 16 Apr 93, this flag is never used to distinguish > between gcc2 and the native compiler. > > If there is no function corresponding to this block, this meaning > of this flag is undefined. */ > > unsigned char gcc_compile_flag; > }; > > #define BLOCK_START(bl) (bl)->startaddr > #define BLOCK_END(bl) (bl)->endaddr > #define BLOCK_FUNCTION(bl) (bl)->function > #define BLOCK_SUPERBLOCK(bl) (bl)->superblock > #define BLOCK_DICT(bl) (bl)->dict > #define BLOCK_NAMESPACE(bl) (bl)->language_specific.cplus_specific.namespace > #define BLOCK_GCC_COMPILED(bl) (bl)->gcc_compile_flag > > struct blockvector > { > /* Number of blocks in the list. */ > int nblocks; > /* The blocks themselves. */ > struct block *block[1]; > }; > > #define BLOCKVECTOR_NBLOCKS(blocklist) (blocklist)->nblocks > #define BLOCKVECTOR_BLOCK(blocklist,n) (blocklist)->block[n] > > /* Special block numbers */ > > #define GLOBAL_BLOCK 0 > #define STATIC_BLOCK 1 > #define FIRST_LOCAL_BLOCK 2 > > extern struct symbol *block_function (const struct block *); > > extern int contained_in (const struct block *, const struct block *); > > /* NOTE: carlton/2002-11-27: I'm a little bit torn about whether many > of these should go here or in cp-support.h. I ended up putting > them here, since they really do use the block structure, but one > could argue with my decision. */ > > extern struct using_direct_node *block_using (const struct block *); > > extern struct using_direct_node *block_all_usings (const struct block *block); > > extern void block_set_using (struct block *block, > struct using_direct_node *using, > struct obstack *obstack); > > extern const char *block_scope (const struct block *block); > > extern void block_set_scope (struct block *block, const char *scope, > struct obstack *obstack); > > extern const struct block *block_static_block (const struct block *block); > > /* In an ideal world, this would be opaque: don't access it directly, > just use the iterator functions. */ > > struct block_using_iterator > { > const struct block *current_block; > const struct using_direct_node *next_node; > }; > > /* Initialize ITERATOR to point at the first using directive valid for > BLOCK, and return that using directive, or NULL if there aren't > any. */ > > extern struct > using_direct *block_using_iterator_first (const struct block *block, > struct block_using_iterator > *iterator); > > /* Advance ITERATOR, and return the next using directive, or NULL if > there aren't any more. Don't call this if you've previously > received NULL from block_using_iterator_first or > block_using_iterator_next during this iteration. */ > > extern struct > using_direct *block_using_iterator_next (struct block_using_iterator > *iterator); > > /* Allocate a dummy block. See warnings before the source code of > this function about using it correctly. */ > > extern struct block *allocate_block (struct obstack *obstack);