+2003-02-21 David Carlton <carlton@math.stanford.edu>
+
+ * linespec.c (locate_compound_sym): Update call to
+ lookup_symbol_namespace.
+ * symtab.c (make_symbol_overload_list): Delete namespace_len
+ argument.
+ * symtab.h: Update declaration for make_symbol_overload_list.
+ * valops.c (find_oload_champ_namespace_loop): New format for
+ make_symbol_overload_list.
+ * symtab.c (lookup_symbol_namespace): Delete namespace_len
+ argument.
+ (lookup_symbol_aux_using_loop): Update call to
+ lookup_symbol_namespace.
+ (make_symbol_overload_list_using): Delete namespace_len argument.
+ * linespec.c (decode_namespace): Update call to
+ lookup_symbol_namespace.
+ * valops.c (value_namespace_elt): Ditto.
+ * symtab.c (lookup_nested_type): Ditto.
+ * symtab.h: Update declaration for lookup_symbol_namespace.
+ * block.c (block_all_usings): Delete.
+ (block_using): Make static.
+ (block_using_iterator_next): New using_direct format.
+ (block_using_iterator_first): Ditto.
+ * buildsym.c (scan_for_anonymous_namespaces): Rename variables.
+ (add_using_directive): New using functions.
+ (end_symtab): Use cp_copy_usings.
+ (copy_usings_to_obstack): Delete.
+ * block.c: Tweak initial comment.
+ (struct namespace_info): Move here.
+ (block_initialize_namespace): Set scope to NULL!
+ * block.h: Add compilation guards.
+ Reorder and update declarations.
+ * cp-support.c (cp_find_first_component): Return unsigned int.
+ (cp_entire_prefix_len): New.
+ (cp_add_using_obstack): Delete.
+ (cp_add_using_xmalloc): Delete.
+ (cp_copy_usings): Rewrite.
+ (cp_free_usings): Delete.
+ (cp_add_using): New.
+ (cp_is_anonymous): Delete second argument.
+ (xstrndup): New.
+ * cp-support.h: Add compilation guards.
+ Update declarations.
+ * coffread.c: New variable coff_source_file.
+ (coff_start_symtab): Use coff_source_file.
+ (complete_symtab): Ditto.
+ (coff_end_symtab): Ditto.
+ (coff_symtab_read): Ditto.
+ * dbxread.c (find_stab_function_addr): Const fix.
+ * buildsym.h: Const fix.
+ * buildsym.c (start_symtab): Const fix.
+ (start_subfile): Ditto.
+ * cp-support.c (cp_add_using_xmalloc): Copy name.
+ * dwarf2read.c (read_namespace): Loop through extensions
+ correctly.
+ (read_file_scope): Const fix.
+ (dwarf2_add_field): Ditto.
+ (read_structure_scope): Ditto.
+ (read_enumeration): Ditto.
+ (read_typedef): Ditto.
+ * buildsym.c (finish_block): Update comments and simplify code
+ when setting scope.
+ * buildsym.h: Add opaque declaration of 'struct block'.
+ Change comment before processing_current_prefix.
+ * arm-tdep.c (arm_gdbarch_init): Add break; after default:.
+
+2003-02-14 Daniel Jacobowitz <drow@mvista.com>
+
+ * dwarf2read.c (dwarf2_get_pc_bounds): Offset addresses by base.
+
2003-02-19 David Carlton <carlton@math.stanford.edu>
* mdebugread.c (new_block): Add 'function' arg.
default:
/* Leave it as "unknown". */
+ break;
}
}
-/* Block support for the GNU debugger, GDB.
+/* Block-related functions for the GNU debugger, GDB.
- Copyright 2002 Free Software Foundation, Inc.
+ Copyright 2003 Free Software Foundation, Inc.
This file is part of GDB.
#include "gdb_obstack.h"
#include "cp-support.h"
+/* This is used by struct block to store namespace-related info for
+ C++ files, namely using declarations and the current namespace in
+ scope. */
+
+struct namespace_info
+{
+ const char *scope;
+ struct using_direct *using;
+};
+
+static struct using_direct *block_using (const struct block *);
+
static void block_initialize_namespace (struct block *block,
struct obstack *obstack);
+/* Return Nonzero if block a is lexically nested within block b,
+ or if a and b have the same pc range.
+ Return zero otherwise. */
+
+int
+contained_in (const struct block *a, const struct block *b)
+{
+ if (!a || !b)
+ return 0;
+ return BLOCK_START (a) >= BLOCK_START (b)
+ && BLOCK_END (a) <= BLOCK_END (b);
+}
+
+
/* Return the symbol for the function which contains a specified
lexical block, described by a struct block BL. */
return BLOCK_FUNCTION (bl);
}
-/* Return Nonzero if block A is lexically nested within block B,
- or if A and B have the same pc range.
- Return zero otherwise. */
-
-int
-contained_in (const struct block *a, const struct block *b)
-{
- if (!a || !b)
- return 0;
- return BLOCK_START (a) >= BLOCK_START (b) && BLOCK_END (a) <= BLOCK_END (b);
-}
-
/* Now come some functions designed to deal with C++ namespace issues.
The accessors are safe to use even in the non-C++ case. */
/* This returns the using directives associated to BLOCK (but _not_
its parents), if any. */
-struct using_direct_node *
+static struct using_direct *
block_using (const struct block *block)
{
if (BLOCK_NAMESPACE (block) == NULL)
return BLOCK_NAMESPACE (block)->using;
}
-/* This returns the using directives associated to BLOCK and its
- parents, if any. The resulting structure must be freed by calling
- cp_free_usings on it. */
-
-struct using_direct_node *
-block_all_usings (const struct block *block)
-{
- struct using_direct_node *using = NULL;
-
- while (block != NULL)
- {
- using = cp_copy_usings (block_using (block), using);
- block = BLOCK_SUPERBLOCK (block);
- }
-
- return using;
-}
-
/* Set block_using (BLOCK) to USING; if needed, allocate memory via
OBSTACK. */
void
-block_set_using (struct block *block, struct using_direct_node *using,
+block_set_using (struct block *block, struct using_direct *using,
struct obstack *obstack)
{
block_initialize_namespace (block, obstack);
{
BLOCK_NAMESPACE (block)
= obstack_alloc (obstack, sizeof (struct namespace_info));
+ BLOCK_NAMESPACE (block)->scope = NULL;
BLOCK_NAMESPACE (block)->using = NULL;
}
}
BLOCK, and return that using directive, or NULL if there aren't
any. */
-struct using_direct *
+const struct using_direct *
block_using_iterator_first (const struct block *block,
struct block_using_iterator *iterator)
{
return NULL;
iterator->current_block = block;
- iterator->next_node = block_using (block);
+ iterator->next_directive = block_using (block);
return block_using_iterator_next (iterator);
}
received NULL from block_using_iterator_first or
block_using_iterator_next during this iteration. */
-struct using_direct *
+const struct using_direct *
block_using_iterator_next (struct block_using_iterator *iterator)
{
- if (iterator->next_node != NULL)
+ if (iterator->next_directive != NULL)
{
- struct using_direct *retval = iterator->next_node->current;
- iterator->next_node = iterator->next_node->next;
+ const struct using_direct *retval = iterator->next_directive;
+ iterator->next_directive = retval->next;
return retval;
}
else
{
iterator->current_block
= BLOCK_SUPERBLOCK (iterator->current_block);
- iterator->next_node = block_using (iterator->current_block);
- if (iterator->next_node != NULL)
+ iterator->next_directive = block_using (iterator->current_block);
+ if (iterator->next_directive != NULL)
{
- struct using_direct *retval = iterator->next_node->current;
- iterator->next_node = iterator->next_node->next;
+ const struct using_direct *retval = iterator->next_directive;
+ iterator->next_directive = retval->next;
return retval;
}
}
-/* 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.
+/* Code dealing with blocks for GDB.
+
+ Copyright 2003 Free Software Foundation, Inc.
This file is part of GDB.
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#ifndef BLOCK_H
+#define BLOCK_H
+
+/* Opaque declarations. */
+
+struct symbol;
+struct dictionary;
+struct namespace_info;
+struct using_direct;
+struct obstack;
+
/* 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.
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
{
#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_NAMESPACE(bl) (bl)->language_specific.cplus_specific.namespace
#define BLOCK_GCC_COMPILED(bl) (bl)->gcc_compile_flag
struct blockvector
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 void block_set_using (struct block *block,
+ struct using_direct *using,
+ 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,
struct block_using_iterator
{
const struct block *current_block;
- const struct using_direct_node *next_node;
+ const struct using_direct *next_directive;
};
/* 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
+extern const struct
using_direct *block_using_iterator_first (const struct block *block,
struct block_using_iterator
*iterator);
received NULL from block_using_iterator_first or
block_using_iterator_next during this iteration. */
-extern struct
+extern const struct
using_direct *block_using_iterator_next (struct block_using_iterator
*iterator);
this function about using it correctly. */
extern struct block *allocate_block (struct obstack *obstack);
+
+#endif /* BLOCK_H */
#include "bfd.h"
#include "gdb_obstack.h"
#include "symtab.h"
-#include "block.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdbtypes.h"
#include "filenames.h" /* For DOSish file names */
#include "macrotab.h"
#include "demangle.h" /* Needed by SYMBOL_INIT_DEMANGLED_NAME. */
+#include "block.h"
#include "dictionary.h"
#include "gdb_assert.h"
#include "cp-support.h"
/* List of using directives that are active in the current file. */
-static struct using_direct_node *using_list;
+static struct using_direct *using_list;
\f
static int compare_line_numbers (const void *ln1p, const void *ln2p);
static void scan_for_anonymous_namespaces (struct symbol *symbol);
-
-static struct using_direct_node *copy_usings_to_obstack (struct
- using_direct_node
- *usings,
- struct obstack
- *obstack);
\f
/* Initial sizes of data structures. These are realloc'd larger if
scan_for_anonymous_namespaces (struct symbol *symbol)
{
const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
- int old_index;
- int new_index;
+ unsigned int previous_component;
+ unsigned int next_component;
const char *len;
/* Start with a quick-and-dirty check for mention of "(anonymous
namespace)". */
- if (!cp_is_anonymous (name, -1))
+ if (!cp_is_anonymous (name))
return;
- old_index = 0;
- new_index = cp_find_first_component (name + old_index);
+ previous_component = 0;
+ next_component = cp_find_first_component (name + previous_component);
- while (name[new_index] == ':')
+ while (name[next_component] == ':')
{
- if ((new_index - old_index) == ANONYMOUS_NAMESPACE_LEN
- && strncmp (name + old_index, "(anonymous namespace)",
+ if ((next_component - previous_component) == ANONYMOUS_NAMESPACE_LEN
+ && strncmp (name + previous_component,
+ "(anonymous namespace)",
ANONYMOUS_NAMESPACE_LEN) == 0)
{
/* We've found a component of the name that's an anonymous
by the previous component if there is one, or to the
global namespace if there isn't. */
add_using_directive (name,
- old_index == 0 ? 0 : old_index - 2,
- new_index);
+ previous_component == 0
+ ? 0 : previous_component - 2,
+ next_component);
}
/* The "+ 2" is for the "::". */
- old_index = new_index + 2;
- new_index = old_index + cp_find_first_component (name + old_index);
+ previous_component = next_component + 2;
+ next_component = (previous_component
+ + cp_find_first_component (name + previous_component));
}
}
return (NULL);
}
-/* This adds a using directive to using_list. NAME is the start of a
- string that should contain the namespaces we want to add as initial
+/* Add a using directive to using_list. NAME is the start of a string
+ that should contain the namespaces we want to add as initial
substrings, OUTER_LENGTH is the end of the outer namespace, and
INNER_LENGTH is the end of the inner namespace. If the using
directive in question has already been added, don't add it
add_using_directive (const char *name, unsigned int outer_length,
unsigned int inner_length)
{
- struct using_direct_node *current;
- struct using_direct_node *new_node;
- struct using_direct *new;
-
- gdb_assert (outer_length < inner_length);
+ struct using_direct *current;
+ struct using_direct *new_node;
/* Has it already been added? */
- for (current = using_list; current; current = current->next)
- if (current->current->outer_length == outer_length
- && current->current->inner_length == inner_length
- && (strncmp (current->current->name, name, inner_length) == 0))
- return;
+ for (current = using_list; current != NULL; current = current->next)
+ {
+ if ((strncmp (current->inner, name, inner_length) == 0)
+ && (strlen (current->inner) == inner_length)
+ && (strlen (current->outer) == outer_length))
+ return;
+ }
- using_list = cp_add_using_xmalloc (name, outer_length, inner_length,
- using_list);
+ using_list = cp_add_using (name, inner_length, outer_length,
+ using_list);
}
/* At end of reading syms, or in case of quit, really free as many
}
}
- /* If we're in the C++ case, make sure that we add 'using'
- directives for all of the namespaces in which this function
- lives. Also, make sure that the name was originally mangled:
- if not, there certainly isn't any namespace information to
- worry about! (Also, if not, the gdb_assert will fail.) */
+ /* If we're in the C++ case, record the namespace that the
+ function was defined in. Make sure that the name was
+ originally mangled: if not, there certainly isn't any
+ namespace information to worry about! */
if (SYMBOL_LANGUAGE (symbol) == language_cplus
&& SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL)
{
- const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
- const char *next;
-
if (processing_has_namespace_info)
- block_set_scope (block, processing_current_prefix,
- &objfile->symbol_obstack);
+ {
+ block_set_scope
+ (block, obsavestring (processing_current_prefix,
+ strlen (processing_current_prefix),
+ &objfile->symbol_obstack),
+ &objfile->symbol_obstack);
+ }
else
{
- const char *current, *next;
+ /* Try to figure out the appropriate namespace from the
+ demangled name. */
- /* FIXME: carlton/2002-11-14: For members of classes,
- with this include the class name as well? I don't
- think that's a problem yet, but it will be. */
+ /* FIXME: carlton/2003-02-21: If the function in
+ question is a method of a class, the name will
+ actually include the name of the class as well. This
+ should be harmless, but is a little unfortunate. */
- current = name;
- next = current + cp_find_first_component (current);
- while (*next == ':')
- {
- current = next;
- /* The '+ 2' is to skip the '::'. */
- next = current + 2;
- next += cp_find_first_component (next);
- }
- if (current == name)
- block_set_scope (block, "", &objfile->symbol_obstack);
- else
- block_set_scope (block,
- obsavestring (name, current - name,
- &objfile->symbol_obstack),
- &objfile->symbol_obstack);
-
- /* FIXME: carlton/2002-10-09: Until I understand the
- possible pitfalls of demangled names a lot better, I
- want to make sure I'm not running into surprises. */
- gdb_assert (*next == '\0');
+ const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
+ unsigned int prefix_len = cp_entire_prefix_len (name);
+
+ block_set_scope (block,
+ obsavestring (name, prefix_len,
+ &objfile->symbol_obstack),
+ &objfile->symbol_obstack);
}
}
}
the directory in which it resides (or NULL if not known). */
void
-start_subfile (char *name, char *dirname)
+start_subfile (const char *name, char *dirname)
{
register struct subfile *subfile;
one original source file. */
void
-start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
+start_symtab (const char *name, char *dirname, CORE_ADDR start_addr)
{
last_source_file = name;
if (using_list != NULL)
{
block_set_using (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK),
- copy_usings_to_obstack (using_list,
- &objfile->symbol_obstack),
+ cp_copy_usings (using_list,
+ &objfile->symbol_obstack),
&objfile->symbol_obstack);
using_list = NULL;
}
return symtab;
}
-/* This reallocates USINGS using OBSTACK and xfree's USINGS. It
- returns the reallocated version of USINGS. */
-
-static struct using_direct_node *
-copy_usings_to_obstack (struct using_direct_node *usings,
- struct obstack *obstack)
-{
- if (usings == NULL)
- return NULL;
- else
- {
- struct using_direct_node *new_node
- = cp_add_using_obstack (usings->current->name,
- usings->current->outer_length,
- usings->current->inner_length,
- copy_usings_to_obstack (usings->next,
- obstack),
- obstack);
-
- xfree (usings->current);
- xfree (usings);
-
- return new_node;
- }
-}
-
/* Push a context block. Args are an identifying nesting level
(checkable when you pop it), and the starting PC address of this
context. */
normally extern, but which get defined in a single module using
this technique. */
+struct block;
+
#ifndef EXTERN
#define EXTERN extern
#endif
/* Name of source file whose symbol data we are now processing. This
comes from a symbol of type N_SO. */
-EXTERN char *last_source_file;
+EXTERN const char *last_source_file;
/* Core address of start of text of current source file. This too
comes from the N_SO symbol. */
/* If processing_has_namespace_info is nonzero, this string should
contain the name of the current prefix (namespaces plus classes).
- Other people shouldn't have to copy it when referring to it, so
- don't free its previous contents when setting this to a new
- value. */
+ The string is temporary; copy it if you need it. */
EXTERN const char *processing_current_prefix;
extern void really_free_pendings (void *dummy);
-extern void start_subfile (char *name, char *dirname);
+extern void start_subfile (const char *name, char *dirname);
extern void patch_subfile_names (struct subfile *subfile, char *name);
extern void record_line (struct subfile *subfile, int line, CORE_ADDR pc);
-extern void start_symtab (char *name, char *dirname, CORE_ADDR start_addr);
+extern void start_symtab (const char *name, char *dirname,
+ CORE_ADDR start_addr);
extern int hashname (char *name);
unsigned int c_type;
};
+/* When starting a symtab, this is the file name. */
+
+static char *coff_source_file;
+
extern void stabsread_clear_cache (void);
static struct type *coff_read_struct_type (int, int, int);
static void
coff_start_symtab (char *name)
{
- start_symtab (
/* We fill in the filename later. start_symtab puts
this pointer into last_source_file and we put it in
subfiles->name, which end_symtab frees; that's why
it must be malloc'd. */
- savestring (name, strlen (name)),
+ coff_source_file = savestring (name, strlen (name));
+
+ start_symtab (coff_source_file,
/* We never know the directory name for COFF. */
NULL,
/* The start address is irrelevant, since we set
static void
complete_symtab (char *name, CORE_ADDR start_addr, unsigned int size)
{
- if (last_source_file != NULL)
- xfree (last_source_file);
- last_source_file = savestring (name, strlen (name));
+ if (coff_source_file != NULL)
+ xfree (coff_source_file);
+ coff_source_file = savestring (name, strlen (name));
+ last_source_file = coff_source_file;
current_source_start_addr = start_addr;
current_source_end_addr = start_addr + size;
/* Reinitialize for beginning of new file. */
last_source_file = NULL;
+ coff_source_file = NULL;
}
\f
static void
nlist_bfd_global = objfile->obfd;
nlist_nsyms_global = nsyms;
last_source_file = NULL;
+ coff_source_file = NULL;
memset (opaque_type_chain, 0, sizeof opaque_type_chain);
if (type_vector) /* Get rid of previous one */
/* Helper routines for C++ support in GDB.
- Copyright 2002 Free Software Foundation, Inc.
+ Copyright 2002, 2003 Free Software Foundation, Inc.
- Contributed by MontaVista Software and by David Carlton, Stanford
- University.
+ Contributed by MontaVista Software and Stanford University.
This file is part of GDB.
#include "cp-support.h"
#include "gdb_string.h"
#include "demangle.h"
-#include "gdb_obstack.h"
#include "gdb_assert.h"
+#include "gdb_obstack.h"
#include "symtab.h"
#include "symfile.h"
#include "block.h"
#include "dictionary.h"
#include "gdbcmd.h"
+static char *xstrndup (const char *string, size_t len);
+
static const char *find_last_component (const char *name);
/* This block exists only to store symbols associated to namespaces.
a template argument might be a type that's a function.
- Conversely, even if you're trying to deal with a function, its
- demangled name might not end with ')': it could be a const (or
- volatile, I suppose) class method, in which case it ends with
- "const".
+ demangled name might not end with ')': it could be a const or
+ volatile class method, in which case it ends with "const" or
+ "volatile".
- Parentheses are also used in anonymous namespaces: a variable
'foo' in an anonymous namespace gets demangled as "(anonymous
return ret;
}
-/* This allocates a new using_direct structure initialized to contain
- NAME, OUTER_LENGTH, and INNER_LENGTH, and puts it at the beginning
- of the linked list given by NEXT. It returns the resulting struct
- using_direct_node. All memory is allocated using OBSTACK. */
-
-struct using_direct_node *
-cp_add_using_obstack (const char *name,
- unsigned short outer_length,
- unsigned short inner_length,
- struct using_direct_node *next,
- struct obstack *obstack)
-{
- struct using_direct *current
- = obstack_alloc (obstack, sizeof (struct using_direct));
- struct using_direct_node *retval
- = obstack_alloc (obstack, sizeof (struct using_direct_node));
-
- gdb_assert (outer_length < inner_length);
-
- current->name = name;
- current->outer_length = outer_length;
- current->inner_length = inner_length;
- retval->current = current;
- retval->next = next;
-
- return retval;
-}
-
-/* Same as cp_add_using, except that it uses xmalloc instead of
- obstacks. */
-
-struct using_direct_node *
-cp_add_using_xmalloc (const char *name,
- unsigned short outer_length,
- unsigned short inner_length,
- struct using_direct_node *next)
-{
- struct using_direct *current = xmalloc (sizeof (struct using_direct));
- struct using_direct_node *retval
- = xmalloc (sizeof (struct using_direct_node));
-
- gdb_assert (outer_length < inner_length);
-
- current->name = name;
- current->outer_length = outer_length;
- current->inner_length = inner_length;
- retval->current = current;
- retval->next = next;
-
- return retval;
-}
-
-/* This copies the using_direct_nodes in TOCOPY, using xmalloc, and
- sticks them onto a list ending in TAIL. (It doesn't copy the
- using_directs, just the using_direct_nodes.) */
-
-struct using_direct_node *
-cp_copy_usings (struct using_direct_node *tocopy,
- struct using_direct_node *tail)
-{
- struct using_direct_node *new_node;
-
- if (tocopy == NULL)
- return tail;
-
- new_node = xmalloc (sizeof (struct using_direct_node));
- new_node->current = tocopy->current;
- new_node->next = cp_copy_usings (tocopy->next, tail);
-
- return new_node;
-}
-
-/* This xfree's all the using_direct_nodes in USING (but not their
- using_directs!) */
-void
-cp_free_usings (struct using_direct_node *using)
-{
- struct using_direct_node *next;
-
- if (using != NULL)
- {
- for (next = using->next; next;
- using = next, next = next->next)
- xfree (using);
-
- xfree (using);
- }
-}
-
-
-/* This returns the first component of NAME, which should be the
- demangled name of a C++ variable/function/method/etc.
- Specifically, it returns a pointer to the first colon forming the
+/* This returns the length of first component of NAME, which should be
+ the demangled name of a C++ variable/function/method/etc.
+ Specifically, it returns the index of the first colon forming the
boundary of the first component: so, given 'A::foo' or 'A::B::foo'
- it returns a pointer to the first :, and given 'foo', it returns a
- pointer to the trailing '\0'. */
+ it returns the 1, and given 'foo', it returns 0. */
/* Well, that's what it should do when called externally, but to make
the recursion easier, it also stops if it reaches an unexpected ')'
#define LENGTH_OF_OPERATOR 8
-int
-cp_find_first_component (const char *const name)
+unsigned int
+cp_find_first_component (const char *name)
{
/* Names like 'operator<<' screw up the recursion, so let's
special-case them. I _hope_ they can only occur at the start of
a component. */
- int index = 0;
+ unsigned int index = 0;
if (strncmp (name, "operator", LENGTH_OF_OPERATOR) == 0)
{
}
}
+/* If NAME is the fully-qualified name of a C++
+ function/variable/method/etc., this returns the length of its
+ entire prefix: all of the namespaces and classes that make up its
+ name. Given 'A::foo', it returns 1, given 'A::B::foo', it returns
+ 4, given 'foo', it returns 0. */
+
+unsigned int cp_entire_prefix_len (const char *name)
+{
+ unsigned int current_len = cp_find_first_component (name);
+ unsigned int previous_len = 0;
+
+ while (name[current_len] != '\0')
+ {
+ gdb_assert (name[current_len] == ':');
+ previous_len = current_len;
+ /* Skip the '::'. */
+ current_len += 2;
+ current_len += cp_find_first_component (name + current_len);
+ }
+
+ return previous_len;
+}
+
+/* Create a new struct using direct whose inner namespace is the
+ initial substring of NAME of leng INNER_LEN and whose outer
+ namespace is the initial substring of NAME of length OUTER_LENGTH.
+ Set its next member in the linked list to NEXT; allocate all memory
+ using xmalloc. It copies the strings, so NAME can be a temporary
+ string. */
+
+struct using_direct *
+cp_add_using (const char *name,
+ unsigned int inner_len,
+ unsigned int outer_len,
+ struct using_direct *next)
+{
+ struct using_direct *retval;
+
+ gdb_assert (outer_len < inner_len);
+
+ retval = xmalloc (sizeof (struct using_direct));
+ retval->inner = xstrndup (name, inner_len);
+ retval->outer = xstrndup (name, outer_len);
+ retval->next = next;
+
+ return retval;
+}
+
+/* Make a copy of the using directives in the list pointed to by
+ USING, using OBSTACK to allocate memory. Free all memory pointed
+ to by USING via xfree. */
+
+extern struct using_direct *
+cp_copy_usings (struct using_direct *using,
+ struct obstack *obstack)
+{
+ if (using == NULL)
+ {
+ return NULL;
+ }
+ else
+ {
+ struct using_direct *retval
+ = obstack_alloc (obstack, sizeof (struct using_direct));
+ retval->inner = obsavestring (using->inner, strlen (using->inner),
+ obstack);
+ retval->outer = obsavestring (using->outer, strlen (using->outer),
+ obstack);
+ retval->next = cp_copy_usings (using->next, obstack);
+
+ xfree (using->inner);
+ xfree (using->outer);
+ xfree (using);
+
+ return retval;
+ }
+}
+
/* Allocate everything necessary for namespace_block and
possible_namespace_block. */
}
}
-/* Test whether or not the initial substring of NAMESPACE_NAME of
- length NAMESPACE_LEN mentions an anonymous namespace.
- NAMESPACE_NAME must be a NULL-terminated string. If NAMESPACE_LEN
- is -1, search the entire string. */
+/* Test whether or not NAMESPACE looks like it mentions an anonymous
+ namespace; return nonzero if so. */
int
-cp_is_anonymous (const char *namespace_name, int namespace_len)
+cp_is_anonymous (const char *namespace)
{
- const char *location = strstr (namespace_name, "(anonymous namespace)");
+ return (strstr (namespace, "(anonymous namespace)")
+ != NULL);
+}
- if (location == NULL)
- return 0;
- else if (namespace_len == -1)
- return 1;
- else
- return (location - namespace_name) < namespace_len;
+/* Create a copy of the initial substring of STRING of length LEN.
+ Allocate memory via xmalloc. */
+
+static char *
+xstrndup (const char *string, size_t len)
+{
+ char *retval = xmalloc (len + 1);
+
+ strncpy (retval, string, len);
+ retval[len] = '\0';
+
+ return retval;
}
/* If FULL_NAME is the demangled name of a C++ function (including an
/* Helper routines for C++ support in GDB.
- Copyright 2002 Free Software Foundation, Inc.
+ Copyright 2002, 2003 Free Software Foundation, Inc.
- Contributed by MontaVista Software and by David Carlton, Stanford
- University.
+ Contributed by MontaVista Software and Stanford University.
This file is part of GDB.
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#ifndef CP_SUPPORT_H
+#define CP_SUPPORT_H
+
/* Opaque declarations. */
struct obstack;
struct symbol;
-extern char *class_name_from_physname (const char *physname);
-
-extern char *method_name_from_physname (const char *physname);
-
-extern int cp_find_first_component (const char *name);
-
-/* This is a struct to store data from "using directives" and similar
- language constructs. NAME is a pointer to a string; its initial
- substrings of length OUTER_LENGTH and INNER_LENGTH should both be
- fully-qualified namespace names. (And OUTER_LENGTH should be
- strictly less than INNER_LENGTH). The meaning is that names in the
- inner namespace should be imported into outer.
-
- For example, if it is used to represent the directive "using
- namespace std;" then NAME should start with "std", INNER_LENGTH
- should be 0, and OUTER_LENGTH should be "3". For a more
- complicated example, if there is an anonymous namespace with a
- named namespace A, then NAME should start with "A::(anonymous
- namespace)", INNER_LENGTH should be 1, and OUTER_LENGTH should be
- strlen ("A::(anonymous namespace)"). */
-
-/* FIXME: carlton/2002-10-07: That anonymous namespace example isn't
- that great, since it really depends not only on what the
- demangler's output is but also on the fact that the demangler's
- output doesn't depend on the name of the file in question. Which,
- alas, it doesn't, but should, leaving us with no way to distinguish
- between anonymous namespaces in different files. Sigh... */
+/* This struct is designed to store data from using directives. It
+ says that names from namespace INNER should be visible within
+ namespace OUTER. OUTER should always be a strict initial substring
+ of INNER. These form a linked list; NEXT is the next element of
+ the list. */
struct using_direct
{
- const char *name;
- unsigned short outer_length;
- unsigned short inner_length;
-};
-
-/* This is a struct for a linked list of using_direct's. */
-
-struct using_direct_node
-{
- struct using_direct *current;
- struct using_direct_node *next;
+ char *inner;
+ char *outer;
+ struct using_direct *next;
};
-/* This is used by struct block to store namespace-related info for
- C++ files, namely using declarations and the current namespace in
- scope. */
+extern char *class_name_from_physname (const char *physname);
-struct namespace_info
-{
- struct using_direct_node *using;
- const char *scope;
-};
+extern char *method_name_from_physname (const char *physname);
-extern struct
-using_direct_node *cp_add_using_obstack (const char *name,
- unsigned short outer_length,
- unsigned short inner_length,
- struct using_direct_node *next,
- struct obstack *obstack);
+extern unsigned int cp_find_first_component (const char *name);
-extern
-struct using_direct_node *cp_add_using_xmalloc (const char *name,
- unsigned short outer_length,
- unsigned short inner_length,
- struct using_direct_node
- *next);
+extern unsigned int cp_entire_prefix_len (const char *name);
-extern
-struct using_direct_node *cp_copy_usings (struct using_direct_node *tocopy,
- struct using_direct_node *tail);
+extern struct using_direct *cp_add_using (const char *name,
+ unsigned int inner_len,
+ unsigned int outer_len,
+ struct using_direct *next);
-extern void cp_free_usings (struct using_direct_node *using);
+extern struct using_direct *cp_copy_usings (struct using_direct *using,
+ struct obstack *obstack);
extern struct symbol *cp_check_namespace_symbol (const char *name, int len);
extern struct symbol *cp_lookup_possible_namespace_symbol (const char *name);
-extern int cp_is_anonymous (const char *namespace_name, int namespace_len);
+extern int cp_is_anonymous (const char *namespace);
extern char *cp_func_name (const char *full_name);
+
+#endif /* CP_SUPPORT_H */
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
CORE_ADDR
-find_stab_function_addr (char *namestring, char *filename,
+find_stab_function_addr (char *namestring, const char *filename,
struct objfile *objfile)
{
struct minimal_symbol *msym;
static char *dwarf2_linkage_name (struct die_info *);
-static char *dwarf2_name (struct die_info *);
+static char *dwarf2_name (struct die_info *die);
static struct die_info *dwarf2_extension (struct die_info *die);
static void initialize_cu_func_list (void);
-static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR);
+static void add_to_cu_func_list (char *, CORE_ADDR, CORE_ADDR);
static void dwarf_decode_macros (struct line_header *, unsigned int,
char *, bfd *, const struct comp_unit_head *,
CORE_ADDR lowpc = ((CORE_ADDR) -1);
CORE_ADDR highpc = ((CORE_ADDR) 0);
struct attribute *attr;
- char *name;
+ const char *name;
char *comp_dir = NULL;
struct die_info *child_die;
bfd *abfd = objfile->obfd;
}
static void
-add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc)
+add_to_cu_func_list (char *name, CORE_ADDR lowpc, CORE_ADDR highpc)
{
struct function_range *thisfn;
return 0;
}
+ range_beginning += base;
+ range_end += base;
+
/* FIXME: This is recording everything as a low-high
segment of consecutive addresses. We should have a
data structure for discontiguous block ranges
struct nextfield *new_field;
struct attribute *attr;
struct field *fp;
- char *fieldname;
+ const char *fieldname;
/* Allocate a new field list entry and link it in. */
new_field = (struct nextfield *) xmalloc (sizeof (struct nextfield));
{
struct type *type;
struct attribute *attr;
- char *name;
+ const char *name;
const char *previous_prefix = processing_current_prefix;
/* This says whether or not we want to try to update the structure's
name to include enclosing namespace/class information, if
struct field *fields;
struct attribute *attr;
struct symbol *sym;
- char *name;
+ const char *name;
int num_fields;
int unsigned_enum = 1;
/* Loop through the extensions until we find a name. */
- for (current_die = die; current_die != NULL;
+ for (current_die = die;
+ current_die != NULL;
current_die = dwarf2_extension (die))
{
- name = dwarf2_name (die);
+ name = dwarf2_name (current_die);
if (name != NULL)
break;
}
/* Now build the name of the current namespace. */
- processing_current_prefix = obconcat (&objfile->symbol_obstack,
- previous_prefix,
- previous_prefix[0] == '\0'
- ? "" : "::",
- name);
+ if (previous_prefix[0] == '\0')
+ {
+ processing_current_prefix = name;
+ }
+ else
+ {
+ /* We need temp_name around because processing_current_namespace
+ is a const char *. */
+ char *temp_name = alloca (strlen (previous_prefix)
+ + 2 + strlen(name) + 1);
+ strcpy (temp_name, previous_prefix);
+ strcat (temp_name, "::");
+ strcat (temp_name, name);
+
+ processing_current_prefix = temp_name;
+ }
/* If it's an anonymous namespace that we're seeing for the first
time, add a using directive. */
strlen (previous_prefix),
strlen (processing_current_prefix));
-
if (die->has_children)
{
struct die_info *child_die = die->next;
if (!die->type)
{
name = dwarf2_name (die);
- die->type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name, objfile);
+ die->type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB,
+ name, objfile);
TYPE_TARGET_TYPE (die->type) = die_type (die, objfile, cu_header);
}
}
current_component++;
*argptr = current_component;
- return lookup_symbol_namespace (namespace, strlen (namespace),
- copy, NULL, get_selected_block(0),
+ return lookup_symbol_namespace (namespace, copy, NULL,
+ get_selected_block(0),
VAR_NAMESPACE, NULL);
}
copy[next_component - *argptr] = '\0';
*argptr = next_component;
- sym = lookup_symbol_namespace (namespace, strlen (namespace),
- copy, NULL, get_selected_block(0),
+ sym = lookup_symbol_namespace (namespace, copy, NULL,
+ get_selected_block(0),
VAR_NAMESPACE, &sym_symtab);
if (sym != NULL)
const char *oload_name);
static void make_symbol_overload_list_using (const char *func_name,
- const char *namespace_name,
- int namespace_len,
+ const char *namespace,
const struct block *block);
static void make_symbol_overload_list_qualified (const char *func_name);
const char *scope,
int scope_len)
{
+ char *cp_namespace;
+
if (scope[scope_len] != '\0')
{
struct symbol *sym;
return sym;
}
- return lookup_symbol_namespace (scope, scope_len, name, linkage_name,
+ cp_namespace = alloca (scope_len + 1);
+ strncpy (cp_namespace, scope, scope_len);
+ cp_namespace[scope_len] = '\0';
+ return lookup_symbol_namespace (cp_namespace, name, linkage_name,
block, namespace, symtab);
}
-/* This tries to look up NAME in the namespace given by the initial
- substring of NAMESPACE_NAME of length NAMESPACE_LEN. It applies
- the using directives that are active in BLOCK. It doesn't look
- into NAME at all, so if NAME happens to contain some namespaces, it
- won't apply using directives to those namespaces. */
-
-/* FIXME: carlton/2002-11-27: Currently, there's no way to specify
- that additional using directives are active. When we get around to
- implementing Koenig lookup, that will have to change. */
-
-/* NOTE: carlton/2002-11-27: I'm calling the namespace_enum argument
- NAME_SPACE instead of NAMESPACE because I'm being driven crazy by
- the two different meanings of "namespace" in this function. */
+/* This tries to look up NAME in the C++ namespace CP_NAMESPACE. It
+ applies the using directives that are active in BLOCK. Otherwise,
+ arguments are as in lookup_symbol_aux. */
struct symbol *
-lookup_symbol_namespace (const char *namespace_name,
- int namespace_len,
+lookup_symbol_namespace (const char *cp_namespace,
const char *name,
const char *linkage_name,
const struct block *block,
- namespace_enum name_space,
+ namespace_enum gdb_namespace,
struct symtab **symtab)
{
struct block_using_iterator iter;
current != NULL;
current = block_using_iterator_next (&iter))
{
- if (namespace_len == current->outer_length
- && strncmp (namespace_name, current->name, namespace_len) == 0)
+ if (strcmp (cp_namespace, current->outer) == 0)
{
- sym = lookup_symbol_namespace (current->name,
- current->inner_length,
+ sym = lookup_symbol_namespace (current->inner,
name,
linkage_name,
block,
- name_space,
+ gdb_namespace,
symtab);
if (sym != NULL)
return sym;
that are still applicable; so let's see if we've got a match
using the current namespace. */
- if (namespace_len == 0)
+ if (cp_namespace[0] == '\0')
{
return lookup_symbol_aux_file (name, linkage_name, block,
- name_space, symtab,
+ gdb_namespace, symtab,
0);
}
else
{
char *concatenated_name
- = alloca (namespace_len + 2 + strlen (name) + 1);
- strncpy (concatenated_name, namespace_name, namespace_len);
- strcpy (concatenated_name + namespace_len, "::");
- strcpy (concatenated_name + namespace_len + 2, name);
+ = alloca (strlen (cp_namespace) + 2 + strlen (name) + 1);
+ strcpy (concatenated_name, cp_namespace);
+ strcat (concatenated_name, "::");
+ strcat (concatenated_name, name);
sym = lookup_symbol_aux_file (concatenated_name, linkage_name,
- block, name_space, symtab,
- cp_is_anonymous (namespace_name,
- namespace_len));
-
+ block, gdb_namespace, symtab,
+ cp_is_anonymous (cp_namespace));
return sym;
}
}
something. */
const char *parent_name = TYPE_TAG_NAME (parent_type);
struct symbol *sym = lookup_symbol_namespace (parent_name,
- strlen (parent_name),
nested_name,
NULL,
block,
struct symbol **
make_symbol_overload_list (const char *func_name,
- const char *namespace_name,
- int namespace_len, const struct block *block)
+ const char *namespace,
+ const struct block *block)
{
struct cleanup *old_cleanups;
old_cleanups = make_cleanup (xfree, sym_return_val);
- make_symbol_overload_list_using (func_name, namespace_name,
- namespace_len, block);
+ make_symbol_overload_list_using (func_name, namespace,
+ block);
discard_cleanups (old_cleanups);
static void
make_symbol_overload_list_using (const char *func_name,
- const char *namespace_name,
- int namespace_len,
+ const char *namespace,
const struct block *block)
{
struct block_using_iterator iter;
current != NULL;
current = block_using_iterator_next (&iter))
{
- if (namespace_len == current->outer_length
- && strncmp (namespace_name, current->name, namespace_len) == 0)
+ if (strcmp (namespace, current->outer) == 0)
{
make_symbol_overload_list_using (func_name,
- current->name,
- current->inner_length,
+ current->inner,
block);
}
}
/* Now, add names for this namespace. */
- if (namespace_len == 0)
+ if (namespace[0] == '\0')
{
make_symbol_overload_list_qualified (func_name);
}
else
{
char *concatenated_name
- = alloca (namespace_len + 2 + strlen (func_name) + 1);
- strncpy (concatenated_name, namespace_name, namespace_len);
- strcpy (concatenated_name + namespace_len, "::");
- strcpy (concatenated_name + namespace_len + 2, func_name);
+ = alloca (strlen (namespace) + 2 + strlen (func_name) + 1);
+ strcpy (concatenated_name, namespace);
+ strcat (concatenated_name, "::");
+ strcat (concatenated_name, func_name);
make_symbol_overload_list_qualified (concatenated_name);
}
}
/* Lookup a symbol within a namespace. */
-extern struct symbol *lookup_symbol_namespace (const char *namespace_name,
- int namespace_len,
+extern struct symbol *lookup_symbol_namespace (const char *cp_namespace,
const char *name,
const char *mangled_name,
const struct block *block,
- namespace_enum name_space,
+ namespace_enum gdb_namespace,
struct symtab **symtab);
/* Lookup the symbol associated to a minimal symbol. */
extern char *remove_params (const char *demangled_name);
extern struct symbol **make_symbol_overload_list (const char *,
- const char *, int,
+ const char *,
const struct block *);
extern char **make_source_files_completion_list (char *, char *);
int new_oload_champ;
struct symbol **new_oload_syms;
struct badness_vector *new_oload_champ_bv;
+ char *new_namespace;
if (next_namespace_len != 0)
{
old_cleanups = make_cleanup (xfree, *oload_syms);
old_cleanups = make_cleanup (xfree, *oload_champ_bv);
+ new_namespace = alloca (namespace_len + 1);
+ strncpy (new_namespace, qualified_name, namespace_len);
+ new_namespace[namespace_len] = '\0';
new_oload_syms = make_symbol_overload_list (func_name,
- qualified_name,
- namespace_len,
+ new_namespace,
current_block);
while (new_oload_syms[num_fns])
++num_fns;
const char *namespace_name = TYPE_TAG_NAME (curtype);
const struct symbol *sym;
- sym = lookup_symbol_namespace (namespace_name, strlen (namespace_name),
- name, NULL, block, VAR_NAMESPACE, NULL);
+ sym = lookup_symbol_namespace (namespace_name, name, NULL,
+ block, VAR_NAMESPACE, NULL);
/* FIXME: carlton/2002-11-24: Should this really be here, or should
it be in c-exp.y like the other similar messages? Hmm... */