C++ improvements

This commit is contained in:
Daniel Berlin 2000-06-05 20:49:53 +00:00
parent e6d71bf34e
commit 357e46e7c9
8 changed files with 104 additions and 96 deletions

View file

@ -1,3 +1,27 @@
2000-06-05 Daniel Berlin <dan@cgsoftware.com>
* c-exp.y (yylex): template handling fixes.
2000-06-03 Daniel Berlin <dan@cgsoftware.com>
* symtab.h (VTBL_PREFIX_P): Add newer g++ vtbl prefix to prefix list.
* symtab.c (lookup_partial_symbol): Change to stop forcing linear searches
on C++ when we fail the binary search, by doing the binary search right.
2000-05-30 Daniel Berlin <dan@cgsoftware.com>
* buildsym.c (hashname): Change to use hash function from bcache.c/.h
* bcache.c (hash): Change to newer hash function.
* bcache.h (hash): Prototype for hash function
* dwarf2read.c (TYPE_HASH_SIZE): New define for controlling size
of type hash.
(dwarf2_cached_types): New variable that is the cached types.
(tag_type_to_type): Do the actual caching of types here.
2000-06-05 Mark Kettenis <kettenis@gnu.org> 2000-06-05 Mark Kettenis <kettenis@gnu.org>
* acconfig.h, configure.in, i386bsd.c (HAVE_STRUCT_REG_R_FS): * acconfig.h, configure.in, i386bsd.c (HAVE_STRUCT_REG_R_FS):

View file

@ -28,42 +28,25 @@
#include "bcache.h" #include "bcache.h"
#include "gdb_string.h" /* For memcpy declaration */ #include "gdb_string.h" /* For memcpy declaration */
/* The old hash function was stolen from SDBM. This is what DB 3.0 uses now,
* and is better than the old one.
*/
/* The hash function. */
unsigned long unsigned long
hash (void *addr, int length) hash(void *addr, int length)
{ {
/* If it's a short string, hash on every character. Otherwise, sample const unsigned char *k, *e;
characters from throughout the string. */ unsigned long h;
if (length <= 64)
{ k = (const unsigned char *)addr;
char *byte = addr; e = k+length;
unsigned long h = 0; for (h=0; k< e;++k)
int i; {
h *=16777619;
for (i = 0; i < length; i++) h ^= *k;
h = h * 65793 ^ (h >> (sizeof (h) * 8 - 6)) ^ byte[i]; }
return (h);
return h;
}
else
{
char *byte = addr;
int n, i;
unsigned long h = 0;
for (n = i = 0; n < 64; n++)
{
h = h * 65793 + (h >> (sizeof (h) * 8 - 6)) + byte[i];
i = h % length;
}
return h;
}
} }
/* Growing the bcache's hash table. */ /* Growing the bcache's hash table. */

View file

@ -125,5 +125,6 @@ extern void free_bcache (struct bcache *bcache);
kind of data BCACHE holds. Statistics are printed using kind of data BCACHE holds. Statistics are printed using
`printf_filtered' and its ilk. */ `printf_filtered' and its ilk. */
extern void print_bcache_statistics (struct bcache *bcache, char *type); extern void print_bcache_statistics (struct bcache *bcache, char *type);
/* The hash function */
extern unsigned long hash(void *addr, int length);
#endif /* BCACHE_H */ #endif /* BCACHE_H */

View file

@ -36,7 +36,7 @@
#include "gdb_string.h" #include "gdb_string.h"
#include "expression.h" /* For "enum exp_opcode" used by... */ #include "expression.h" /* For "enum exp_opcode" used by... */
#include "language.h" /* For "longest_local_hex_string_custom" */ #include "language.h" /* For "longest_local_hex_string_custom" */
#include "bcache.h"
/* Ask buildsym.h to define the vars it normally declares `extern'. */ /* Ask buildsym.h to define the vars it normally declares `extern'. */
#define EXTERN #define EXTERN
/**/ /**/
@ -1055,33 +1055,13 @@ push_context (int desc, CORE_ADDR valu)
return new; return new;
} }
/* Compute a small integer hash code for the given name. */ /* Compute a small integer hash code for the given name. */
int int
hashname (char *name) hashname (char *name)
{ {
register char *p = name; return (hash(name,strlen(name)) % HASHSIZE);
register int total = p[0];
register int c;
c = p[1];
total += c << 2;
if (c)
{
c = p[2];
total += c << 4;
if (c)
{
total += p[3] << 6;
}
}
/* Ensure result is positive. */
if (total < 0)
{
total += (1000 << 6);
}
return (total % HASHSIZE);
} }

View file

@ -1433,8 +1433,6 @@ yylex ()
if (c == '<') if (c == '<')
{ {
if (hp_som_som_object_present)
{
/* Scan ahead to get rest of the template specification. Note /* Scan ahead to get rest of the template specification. Note
that we look ahead only when the '<' adjoins non-whitespace that we look ahead only when the '<' adjoins non-whitespace
characters; for comparison expressions, e.g. "a < b > c", characters; for comparison expressions, e.g. "a < b > c",
@ -1444,26 +1442,6 @@ yylex ()
if (p) if (p)
namelen = p - tokstart; namelen = p - tokstart;
break; break;
}
else
{
int i = namelen;
int nesting_level = 1;
while (tokstart[++i])
{
if (tokstart[i] == '<')
nesting_level++;
else if (tokstart[i] == '>')
{
if (--nesting_level == 0)
break;
}
}
if (tokstart[i] == '>')
namelen = i;
else
break;
}
} }
c = tokstart[++namelen]; c = tokstart[++namelen];
} }

View file

@ -35,14 +35,15 @@
#include "buildsym.h" #include "buildsym.h"
#include "demangle.h" #include "demangle.h"
#include "expression.h" #include "expression.h"
#include "language.h" #include "language.h"
#include "complaints.h" #include "complaints.h"
#include "bcache.h"
#include <fcntl.h> #include <fcntl.h>
#include "gdb_string.h" #include "gdb_string.h"
#include <sys/types.h> #include <sys/types.h>
/* .debug_info header for a compilation unit /* .debug_info header for a compilation unit
Because of alignment constraints, this structure has padding and cannot Because of alignment constraints, this structure has padding and cannot
be mapped directly onto the beginning of the .debug_info section. */ be mapped directly onto the beginning of the .debug_info section. */
typedef struct comp_unit_header typedef struct comp_unit_header
@ -267,6 +268,11 @@ static struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE];
static struct die_info *die_ref_table[REF_HASH_SIZE]; static struct die_info *die_ref_table[REF_HASH_SIZE];
#ifndef TYPE_HASH_SIZE
#define TYPE_HASH_SIZE 4096
#endif
static struct type *dwarf2_cached_types[TYPE_HASH_SIZE];
/* Obstack for allocating temporary storage used during symbol reading. */ /* Obstack for allocating temporary storage used during symbol reading. */
static struct obstack dwarf2_tmp_obstack; static struct obstack dwarf2_tmp_obstack;
@ -333,7 +339,7 @@ static int islocal; /* Variable is at the returned offset
static int frame_base_reg; static int frame_base_reg;
static CORE_ADDR frame_base_offset; static CORE_ADDR frame_base_offset;
/* This value is added to each symbol value. FIXME: Generalize to /* This value is added to each symbol value. FIXME: Generalize to
the section_offsets structure used by dbxread (once this is done, the section_offsets structure used by dbxread (once this is done,
pass the appropriate section number to end_symtab). */ pass the appropriate section number to end_symtab). */
static CORE_ADDR baseaddr; /* Add to each symbol value */ static CORE_ADDR baseaddr; /* Add to each symbol value */
@ -3960,9 +3966,9 @@ done:
DW_AT_name: /srcdir/list0.c DW_AT_name: /srcdir/list0.c
DW_AT_comp_dir: /compdir DW_AT_comp_dir: /compdir
files.files[0].name: list0.h files.files[0].name: list0.h
files.files[0].dir: /srcdir files.files[0].dir: /srcdir
files.files[1].name: list0.c files.files[1].name: list0.c
files.files[1].dir: /srcdir files.files[1].dir: /srcdir
The line number information for list0.c has to end up in a single The line number information for list0.c has to end up in a single
@ -4449,7 +4455,38 @@ tag_type_to_type (die, objfile)
} }
else else
{ {
read_type_die (die, objfile); struct attribute *attr;
attr = dwarf_attr (die, DW_AT_name);
if (attr && DW_STRING (attr))
{
char *attrname=DW_STRING (attr);
unsigned long hashval=hash(attrname, strlen(attrname)) % TYPE_HASH_SIZE;
if (dwarf2_cached_types[hashval] != NULL)
{
const char *nameoftype;
nameoftype = TYPE_NAME(dwarf2_cached_types[hashval]) == NULL ? TYPE_TAG_NAME(dwarf2_cached_types[hashval]) : TYPE_NAME(dwarf2_cached_types[hashval]);
if (strcmp(attrname, nameoftype) == 0)
{
die->type=dwarf2_cached_types[hashval];
}
else
{
read_type_die (die, objfile);
dwarf2_cached_types[hashval] = die->type;
}
}
else
{
read_type_die (die, objfile);
dwarf2_cached_types[hashval] = die->type;
}
}
else
{
read_type_die (die, objfile);
}
if (!die->type) if (!die->type)
{ {
dump_die (die); dump_die (die);

View file

@ -954,7 +954,7 @@ lookup_symbol (name, block, namespace, is_a_field_of_this, symtab)
*symtab = NULL; *symtab = NULL;
return 0; return 0;
} }
/* Look, in partial_symtab PST, for symbol NAME. Check the global /* Look, in partial_symtab PST, for symbol NAME. Check the global
symbols if GLOBAL, the static symbols if not */ symbols if GLOBAL, the static symbols if not */
@ -965,20 +965,20 @@ lookup_partial_symbol (pst, name, global, namespace)
int global; int global;
namespace_enum namespace; namespace_enum namespace;
{ {
struct partial_symbol *temp;
struct partial_symbol **start, **psym; struct partial_symbol **start, **psym;
struct partial_symbol **top, **bottom, **center; struct partial_symbol **top, **bottom, **center;
int length = (global ? pst->n_global_syms : pst->n_static_syms); int length = (global ? pst->n_global_syms : pst->n_static_syms);
int do_linear_search = 1; int do_linear_search = 1;
if (length == 0) if (length == 0)
{ {
return (NULL); return (NULL);
} }
start = (global ? start = (global ?
pst->objfile->global_psymbols.list + pst->globals_offset : pst->objfile->global_psymbols.list + pst->globals_offset :
pst->objfile->static_psymbols.list + pst->statics_offset); pst->objfile->static_psymbols.list + pst->statics_offset);
if (global) /* This means we can use a binary search. */ if (global) /* This means we can use a binary search. */
{ {
do_linear_search = 0; do_linear_search = 0;
@ -996,9 +996,7 @@ lookup_partial_symbol (pst, name, global, namespace)
if (!(center < top)) if (!(center < top))
abort (); abort ();
if (!do_linear_search if (!do_linear_search
&& (SYMBOL_LANGUAGE (*center) == language_cplus && (SYMBOL_LANGUAGE (*center) == language_java))
|| SYMBOL_LANGUAGE (*center) == language_java
))
{ {
do_linear_search = 1; do_linear_search = 1;
} }
@ -1013,11 +1011,15 @@ lookup_partial_symbol (pst, name, global, namespace)
} }
if (!(top == bottom)) if (!(top == bottom))
abort (); abort ();
while (STREQ (SYMBOL_NAME (*top), name))
/* djb - 2000-06-03 - Use SYMBOL_MATCHES_NAME, not a strcmp, so
we don't have to force a linear search on C++. Probably holds true
for JAVA as well, no way to check.*/
while (SYMBOL_MATCHES_NAME (*top,name))
{ {
if (SYMBOL_NAMESPACE (*top) == namespace) if (SYMBOL_NAMESPACE (*top) == namespace)
{ {
return (*top); return (*top);
} }
top++; top++;
} }
@ -1027,7 +1029,7 @@ lookup_partial_symbol (pst, name, global, namespace)
we should also do a linear search. */ we should also do a linear search. */
if (do_linear_search) if (do_linear_search)
{ {
for (psym = start; psym < start + length; psym++) for (psym = start; psym < start + length; psym++)
{ {
if (namespace == SYMBOL_NAMESPACE (*psym)) if (namespace == SYMBOL_NAMESPACE (*psym))
@ -4018,6 +4020,7 @@ functions_info (regexp, from_tty)
symtab_symbol_info (regexp, FUNCTIONS_NAMESPACE, from_tty); symtab_symbol_info (regexp, FUNCTIONS_NAMESPACE, from_tty);
} }
static void static void
types_info (regexp, from_tty) types_info (regexp, from_tty)
char *regexp; char *regexp;
@ -4664,6 +4667,7 @@ _initialize_symtab ()
add_info ("functions", functions_info, add_info ("functions", functions_info,
"All function names, or those matching REGEXP."); "All function names, or those matching REGEXP.");
/* FIXME: This command has at least the following problems: /* FIXME: This command has at least the following problems:
1. It prints builtin types (in a very strange and confusing fashion). 1. It prints builtin types (in a very strange and confusing fashion).
2. It doesn't print right, e.g. with 2. It doesn't print right, e.g. with

View file

@ -1059,10 +1059,11 @@ struct partial_symtab
style, using thunks (where '$' is really CPLUS_MARKER). */ style, using thunks (where '$' is really CPLUS_MARKER). */
#define VTBL_PREFIX_P(NAME) \ #define VTBL_PREFIX_P(NAME) \
((NAME)[0] == '_' \ (((NAME)[0] == '_' \
&& (((NAME)[1] == 'V' && (NAME)[2] == 'T') \ && (((NAME)[1] == 'V' && (NAME)[2] == 'T') \
|| ((NAME)[1] == 'v' && (NAME)[2] == 't')) \ || ((NAME)[1] == 'v' && (NAME)[2] == 't')) \
&& is_cplus_marker ((NAME)[3])) && is_cplus_marker ((NAME)[3])) || ((NAME)[0]=='_' && (NAME)[1]=='_' \
&& (NAME)[2]=='v' && (NAME)[3]=='t' && (NAME)[4]=='_'))
/* Macro that yields non-zero value iff NAME is the prefix for C++ destructor /* Macro that yields non-zero value iff NAME is the prefix for C++ destructor
names. Note that this macro is g++ specific (FIXME). */ names. Note that this macro is g++ specific (FIXME). */