aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeoffrey Keating <geoffk@apple.com>2004-05-30 00:49:06 +0000
committerGeoffrey Keating <geoffk@apple.com>2004-05-30 00:49:06 +0000
commitbfe26ddc56ca4f8d31d63844e2b2165c5461a63d (patch)
tree53fb5889181940508762ddb472618440e4b6aca6
parent1229d71afe5228fe5df05a0675db34cc3ba471ad (diff)
Index: libcpp/ChangeLog
2004-05-29 Geoffrey Keating <geoffk@apple.com> * symtab.c (ht_create): Set entries_owned. (ht_destroy): Honour entries_owned. (ht_expand): Likewise. (ht_load): New. Index: libcpp/include/ChangeLog 2004-05-29 Geoffrey Keating <geoffk@apple.com> * symtab.h (struct ht): New field 'entries_owned' (ht_load): New prototype. Index: gcc/ChangeLog 2004-05-29 Geoffrey Keating <geoffk@apple.com> * gengtype-yacc.y: Add NESTED_PTR token. (option): Record `nested_ptr' option. * gengtype-lex.l: Handle `nested_ptr' keyword. * gengtype.c (walk_type): Process `nested_ptr' option. * gengtype.h (struct nested_ptr_data): New. * doc/gty.texi (GTY Options): Document `nested_ptr' option. * stringpool.c (struct string_pool_data): Make 'entries' point to ht_identifier instead of tree. (gt_pch_save_stringpool): Don't adjust pointers. (gt_pch_restore_stringpool): Call ht_load. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@82438 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/doc/gty.texi13
-rw-r--r--gcc/gengtype-lex.l3
-rw-r--r--gcc/gengtype-yacc.y10
-rw-r--r--gcc/gengtype.c46
-rw-r--r--gcc/gengtype.h15
-rw-r--r--gcc/stringpool.c42
-rw-r--r--libcpp/ChangeLog7
-rw-r--r--libcpp/include/ChangeLog5
-rw-r--r--libcpp/include/symtab.h9
-rw-r--r--libcpp/symtab.c24
11 files changed, 149 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 662bf28e60f..00d557730ba 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2004-05-29 Geoffrey Keating <geoffk@apple.com>
+
+ * gengtype-yacc.y: Add NESTED_PTR token.
+ (option): Record `nested_ptr' option.
+ * gengtype-lex.l: Handle `nested_ptr' keyword.
+ * gengtype.c (walk_type): Process `nested_ptr' option.
+ * gengtype.h (struct nested_ptr_data): New.
+ * doc/gty.texi (GTY Options): Document `nested_ptr' option.
+ * stringpool.c (struct string_pool_data): Make 'entries' point to
+ ht_identifier instead of tree.
+ (gt_pch_save_stringpool): Don't adjust pointers.
+ (gt_pch_restore_stringpool): Call ht_load.
+
2004-05-29 Jason Merrill <jason@redhat.com>
* gimplify.c (gimplify_expr): Don't build a statement list
diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi
index d43feca7221..c375e24042d 100644
--- a/gcc/doc/gty.texi
+++ b/gcc/doc/gty.texi
@@ -291,6 +291,19 @@ this field is always @code{NULL}. This is used to avoid requiring
backends to define certain optional structures. It doesn't work with
language frontends.
+@findex nested_ptr
+@item nested_ptr (@var{type}, "@var{to expression}", "@var{from expression}")
+
+The type machinery expects all pointers to point to the start of an
+object. Sometimes for abstraction purposes it's convenient to have
+a pointer which points inside an object. So long as it's possible to
+convert the original object to and from the pointer, such pointers
+can still be used. @var{type} is the type of the original object,
+the @var{to expression} returns the pointer given the original object,
+and the @var{from expression} returns the original object given
+the pointer. The pointer will be available using the @code{%h}
+escape.
+
@findex chain_next
@findex chain_prev
@item chain_next ("@var{expression}")
diff --git a/gcc/gengtype-lex.l b/gcc/gengtype-lex.l
index 19d7691f35e..d7fa27ff3bc 100644
--- a/gcc/gengtype-lex.l
+++ b/gcc/gengtype-lex.l
@@ -1,6 +1,6 @@
/* -*- indented-text -*- */
/* Process source files and output type information.
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -235,6 +235,7 @@ ITYPE {IWORD}({WS}{IWORD})*
"struct"/[^[:alnum:]_] { return STRUCT; }
"enum"/[^[:alnum:]_] { return ENUM; }
"ptr_alias"/[^[:alnum:]_] { return ALIAS; }
+"nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; }
[0-9]+ { return NUM; }
"param"[0-9]*"_is"/[^[:alnum:]_] {
yylval.s = xmemdup (yytext, yyleng, yyleng+1);
diff --git a/gcc/gengtype-yacc.y b/gcc/gengtype-yacc.y
index 02136dc0d29..2e7b6a70575 100644
--- a/gcc/gengtype-yacc.y
+++ b/gcc/gengtype-yacc.y
@@ -1,6 +1,6 @@
/* -*- indented-text -*- */
/* Process source files and output type information.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -44,6 +44,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
%token STRUCT
%token ENUM
%token ALIAS
+%token NESTED_PTR
%token <s>PARAM_IS
%token NUM
%token PERCENTPERCENT "%%"
@@ -279,6 +280,13 @@ option: ID
{ $$ = create_option ($1, (void *)$3); }
| type_option '(' type ')'
{ $$ = create_option ($1, adjust_field_type ($3, NULL)); }
+ | NESTED_PTR '(' type ',' stringseq ',' stringseq ')'
+ {
+ struct nested_ptr_data d =
+ { adjust_field_type ($3, NULL), $5, $7 };
+ $$ = create_option ("nested_ptr",
+ xmemdup (&d, sizeof (d), sizeof (d)));
+ }
;
optionseq: option
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 95c88efd48b..804ef70320a 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1509,6 +1509,7 @@ walk_type (type_p t, struct walk_type_data *d)
int use_param_num = -1;
int use_params_p = 0;
options_p oo;
+ const struct nested_ptr_data *nested_ptr_d = NULL;
d->needs_cast_p = 0;
for (oo = d->opt; oo; oo = oo->next)
@@ -1523,6 +1524,8 @@ walk_type (type_p t, struct walk_type_data *d)
use_params_p = 1;
else if (strcmp (oo->name, "desc") == 0)
desc = (const char *)oo->info;
+ else if (strcmp (oo->name, "nested_ptr") == 0)
+ nested_ptr_d = (const struct nested_ptr_data *)oo->info ;
else if (strcmp (oo->name, "dot") == 0)
;
else if (strcmp (oo->name, "tag") == 0)
@@ -1623,7 +1626,48 @@ walk_type (type_p t, struct walk_type_data *d)
break;
}
- d->process_field (t->u.p, d);
+ if (nested_ptr_d)
+ {
+ const char *oldprevval2 = d->prev_val[2];
+
+ if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
+ {
+ error_at_line (d->line,
+ "field `%s' has invalid "
+ "option `nested_ptr'\n",
+ d->val);
+ return;
+ }
+
+ d->prev_val[2] = d->val;
+ oprintf (d->of, "%*s{\n", d->indent, "");
+ d->indent += 2;
+ d->val = xasprintf ("x%d", d->counter++);
+ oprintf (d->of, "%*s%s %s * %s =\n", d->indent, "",
+ (nested_ptr_d->type->kind == TYPE_UNION
+ ? "union" : "struct"),
+ nested_ptr_d->type->u.s.tag, d->val);
+ oprintf (d->of, "%*s", d->indent + 2, "");
+ output_escaped_param (d, nested_ptr_d->convert_from,
+ "nested_ptr");
+ oprintf (d->of, ";\n");
+
+ d->process_field (nested_ptr_d->type, d);
+
+ oprintf (d->of, "%*s%s = ", d->indent, "",
+ d->prev_val[2]);
+ d->prev_val[2] = d->val;
+ output_escaped_param (d, nested_ptr_d->convert_to,
+ "nested_ptr");
+ oprintf (d->of, ";\n");
+
+ d->indent -= 2;
+ oprintf (d->of, "%*s}\n", d->indent, "");
+ d->val = d->prev_val[2];
+ d->prev_val[2] = oldprevval2;
+ }
+ else
+ d->process_field (t->u.p, d);
}
else
{
diff --git a/gcc/gengtype.h b/gcc/gengtype.h
index 55ece115073..bf3c5624ced 100644
--- a/gcc/gengtype.h
+++ b/gcc/gengtype.h
@@ -37,6 +37,17 @@ enum typekind {
TYPE_PARAM_STRUCT
};
+typedef struct pair *pair_p;
+typedef struct type *type_p;
+typedef unsigned lang_bitmap;
+
+/* Option data for the 'nested_ptr' option. */
+struct nested_ptr_data {
+ type_p type;
+ const char *convert_to;
+ const char *convert_from;
+};
+
/* A way to pass data through to the output end. */
typedef struct options {
struct options *next;
@@ -44,10 +55,6 @@ typedef struct options {
const void *info;
} *options_p;
-typedef struct pair *pair_p;
-typedef struct type *type_p;
-typedef unsigned lang_bitmap;
-
/* A name and a type. */
struct pair {
pair_p next;
diff --git a/gcc/stringpool.c b/gcc/stringpool.c
index 781518b9f7d..d17f31decdd 100644
--- a/gcc/stringpool.c
+++ b/gcc/stringpool.c
@@ -1,5 +1,5 @@
/* String pool for GCC.
- Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -201,7 +201,11 @@ gt_pch_n_S (const void *x)
struct string_pool_data GTY(())
{
- tree * GTY((length ("%h.nslots"))) entries;
+ struct ht_identifier * *
+ GTY((length ("%h.nslots"),
+ nested_ptr (union tree_node, "%h ? GCC_IDENT_TO_HT_IDENT (%h) : NULL",
+ "%h ? HT_IDENT_TO_GCC_IDENT (%h) : NULL")))
+ entries;
unsigned int nslots;
unsigned int nelements;
};
@@ -237,25 +241,20 @@ ht_copy_and_clear (cpp_reader *r ATTRIBUTE_UNUSED, hashnode hp, const void *ht2_
static struct ht *saved_ident_hash;
-/* The hash table contains pointers to the cpp_hashnode inside the
- lang_identifier. The PCH machinery can't handle pointers that refer
- to the inside of an object, so to save the hash table for PCH the
- pointers are adjusted and stored in the variable SPD. */
+/* Prepare the stringpool to be written (by clearing all the cpp parts
+ of each entry) and place the data to be saved in SPD. Save the
+ current state in SAVED_IDENT_HASH so that gt_pch_fixup_stringpool
+ can restore it. */
void
gt_pch_save_stringpool (void)
{
- unsigned int i;
-
spd = ggc_alloc (sizeof (*spd));
spd->nslots = ident_hash->nslots;
spd->nelements = ident_hash->nelements;
- spd->entries = ggc_alloc (sizeof (tree *) * spd->nslots);
- for (i = 0; i < spd->nslots; i++)
- if (ident_hash->entries[i] != NULL)
- spd->entries[i] = HT_IDENT_TO_GCC_IDENT (ident_hash->entries[i]);
- else
- spd->entries[i] = NULL;
+ spd->entries = ggc_alloc (sizeof (spd->entries[0]) * spd->nslots);
+ memcpy (spd->entries, ident_hash->entries,
+ spd->nslots * sizeof (spd->entries[0]));
saved_ident_hash = ht_create (14);
saved_ident_hash->alloc_node = alloc_node;
@@ -274,23 +273,12 @@ gt_pch_fixup_stringpool (void)
}
/* A PCH file has been restored, which loaded SPD; fill the real hash table
- with adjusted pointers from SPD. */
+ from SPD. */
void
gt_pch_restore_stringpool (void)
{
- unsigned int i;
-
- ident_hash->nslots = spd->nslots;
- ident_hash->nelements = spd->nelements;
- ident_hash->entries = xrealloc (ident_hash->entries,
- sizeof (hashnode) * spd->nslots);
- for (i = 0; i < spd->nslots; i++)
- if (spd->entries[i] != NULL)
- ident_hash->entries[i] = GCC_IDENT_TO_HT_IDENT (spd->entries[i]);
- else
- ident_hash->entries[i] = NULL;
-
+ ht_load (ident_hash, spd->entries, spd->nslots, spd->nelements, false);
spd = NULL;
}
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 8ebe6f52bac..71a449504b0 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,10 @@
+2004-05-29 Geoffrey Keating <geoffk@apple.com>
+
+ * symtab.c (ht_create): Set entries_owned.
+ (ht_destroy): Honour entries_owned.
+ (ht_expand): Likewise.
+ (ht_load): New.
+
2004-05-26 Paolo Bonzini <bonzini@gnu.org>
PR bootstrap/15651
diff --git a/libcpp/include/ChangeLog b/libcpp/include/ChangeLog
index f6c47fa6daf..a2f4bc5e3ef 100644
--- a/libcpp/include/ChangeLog
+++ b/libcpp/include/ChangeLog
@@ -1,3 +1,8 @@
+2004-05-29 Geoffrey Keating <geoffk@apple.com>
+
+ * symtab.h (struct ht): New field 'entries_owned'
+ (ht_load): New prototype.
+
2004-05-23 Paolo Bonzini <bonzini@gnu.org>
* cpplib.h: Moved from gcc. Change header guard name.
diff --git a/libcpp/include/symtab.h b/libcpp/include/symtab.h
index 8b793320b56..85e285b419f 100644
--- a/libcpp/include/symtab.h
+++ b/libcpp/include/symtab.h
@@ -1,5 +1,5 @@
/* Hash tables.
- Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
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
@@ -58,6 +58,9 @@ struct ht
/* Table usage statistics. */
unsigned int searches;
unsigned int collisions;
+
+ /* Should 'entries' be freed when it is no longer needed? */
+ bool entries_owned;
};
/* Initialize the hashtable with 2 ^ order entries. */
@@ -75,6 +78,10 @@ extern hashnode ht_lookup (hash_table *, const unsigned char *,
typedef int (*ht_cb) (struct cpp_reader *, hashnode, const void *);
extern void ht_forall (hash_table *, ht_cb, const void *);
+/* Restore the hash table. */
+extern void ht_load (hash_table *ht, hashnode *entries,
+ unsigned int nslots, unsigned int nelements, bool own);
+
/* Dump allocation statistics to stderr. */
extern void ht_dump_statistics (hash_table *);
diff --git a/libcpp/symtab.c b/libcpp/symtab.c
index 39cecedf72f..c80dfa25cc0 100644
--- a/libcpp/symtab.c
+++ b/libcpp/symtab.c
@@ -1,5 +1,5 @@
/* Hash tables.
- Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
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
@@ -68,6 +68,7 @@ ht_create (unsigned int order)
obstack_alignment_mask (&table->stack) = 0;
table->entries = xcalloc (nslots, sizeof (hashnode));
+ table->entries_owned = true;
table->nslots = nslots;
return table;
}
@@ -78,7 +79,8 @@ void
ht_destroy (hash_table *table)
{
obstack_free (&table->stack, NULL);
- free (table->entries);
+ if (table->entries_owned)
+ free (table->entries);
free (table);
}
@@ -199,7 +201,9 @@ ht_expand (hash_table *table)
}
while (++p < limit);
- free (table->entries);
+ if (table->entries_owned)
+ free (table->entries);
+ table->entries_owned = true;
table->entries = nentries;
table->nslots = size;
}
@@ -222,6 +226,20 @@ ht_forall (hash_table *table, ht_cb cb, const void *v)
while (++p < limit);
}
+/* Restore the hash table. */
+void
+ht_load (hash_table *ht, hashnode *entries,
+ unsigned int nslots, unsigned int nelements,
+ bool own)
+{
+ if (ht->entries_owned)
+ free (ht->entries);
+ ht->entries = entries;
+ ht->nslots = nslots;
+ ht->nelements = nelements;
+ ht->entries_owned = own;
+}
+
/* Dump allocation statistics to stderr. */
void