This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [rfc] block.{h,c}


I think it's a great idea.

David Carlton <carlton at math dot stanford dot edu> 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 at math dot stanford dot 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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]