+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
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}")
/* -*- 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.
"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);
/* -*- 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.
%token STRUCT
%token ENUM
%token ALIAS
+%token NESTED_PTR
%token <s>PARAM_IS
%token NUM
%token PERCENTPERCENT "%%"
{ $$ = 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
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)
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)
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
{
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;
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;
/* 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.
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;
};
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;
}
/* 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;
}
+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
+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.
/* 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
/* 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. */
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 *);
/* 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
obstack_alignment_mask (&table->stack) = 0;
table->entries = xcalloc (nslots, sizeof (hashnode));
+ table->entries_owned = true;
table->nslots = nslots;
return table;
}
ht_destroy (hash_table *table)
{
obstack_free (&table->stack, NULL);
- free (table->entries);
+ if (table->entries_owned)
+ free (table->entries);
free (table);
}
}
while (++p < limit);
- free (table->entries);
+ if (table->entries_owned)
+ free (table->entries);
+ table->entries_owned = true;
table->entries = nentries;
table->nslots = size;
}
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