summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-09 20:10:13 +0000
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-09 20:10:13 +0000
commitc39ed964c8cd9aec2fe6060830804416b0856b60 (patch)
tree1238be7fc80d74d8323d5f6c4344a6bb2be0f854
parentf5efe504032463d907b2eb0f4f76a5d68ce45429 (diff)
downloadgcc-c39ed964c8cd9aec2fe6060830804416b0856b60.tar.gz
Index: gcc/ChangeLog
2004-06-09 Geoffrey Keating <geoffk@apple.com> * Makefile.in (CPPLIB_H): Put files in order of inclusion. (CPP_ID_DATA_H): New. (gtype-desc.o): Update dependencies. (GTFILES): Use CPP_ID_DATA_H. Index: gcc/testsuite/ChangeLog 2004-06-09 Geoffrey Keating <geoffk@apple.com> * gcc.dg/pch/macro-4.c: New. * gcc.dg/pch/macro-4.hs: New. Index: libcpp/ChangeLog 2004-06-09 Geoffrey Keating <geoffk@apple.com> * traditional.c (push_replacement_text): Set macro->traditional. (save_replacement_text): Likewise. * pch.c (cpp_write_pch_state): Don't write list of defined macros. (struct save_macro_item): Delete. (struct save_macro_data): Use a character array not the previous structured format. (save_macros): Save macro as text not as internal structures. (cpp_prepare_state): Update for changes to save_macro_data. (cpp_read_state): Don't read macros defined in PCH. Restore -D macros as text. * macro.c (create_iso_definition): Honour alloc_subobject. Clear traditional flag. (_cpp_create_definition): Honour alloc_subobject. * lex.c (cpp_token_val_index): New. * internal.h: Include cpp-id-data.h. (uchar): Move definition to cpp-id-data.h. (U): Likewise. (cpp_macro): Likewise. * directives.c (struct answer): Move to cpp-id-data.h. (do_assert): Honour alloc_subobject. Index: libcpp/include/ChangeLog 2004-06-09 Geoffrey Keating <geoffk@apple.com> * symtab.h (struct ht): Add field 'alloc_subobject'. * cpplib.h (struct cpp_string): Add GTY marker. (enum cpp_token_fld_kind): New. (struct cpp_token): Add GTY markers. (cpp_token_val_index): Prototype. (CPP_HASHNODE_VALUE_IDX): New. (struct cpp_hashnode): Don't skip fields of 'value' when marking. * cpp-id-data.h: New file. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@82851 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/Makefile.in16
-rw-r--r--gcc/gengtype.c53
-rw-r--r--gcc/stringpool.c49
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pch/macro-4.c8
-rw-r--r--gcc/testsuite/gcc.dg/pch/macro-4.hs1
-rw-r--r--libcpp/ChangeLog24
-rw-r--r--libcpp/directives.c25
-rw-r--r--libcpp/include/ChangeLog11
-rw-r--r--libcpp/include/cpp-id-data.h77
-rw-r--r--libcpp/include/cpplib.h68
-rw-r--r--libcpp/include/symtab.h5
-rw-r--r--libcpp/internal.h44
-rw-r--r--libcpp/lex.c22
-rw-r--r--libcpp/macro.c30
-rw-r--r--libcpp/pch.c157
-rw-r--r--libcpp/traditional.c3
18 files changed, 372 insertions, 233 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1184df74999..7f5e57d0efd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2004-06-09 Geoffrey Keating <geoffk@apple.com>
+
+ * Makefile.in (CPPLIB_H): Put files in order of inclusion.
+ (CPP_ID_DATA_H): New.
+ (gtype-desc.o): Update dependencies.
+ (GTFILES): Use CPP_ID_DATA_H.
+
2004-06-09 Mark Mitchell <mark@codesourcery.com>
Revert:
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 2fa566aeea1..fc878543323 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -712,10 +712,11 @@ C_COMMON_H = c-common.h $(SPLAY_TREE_H) $(CPPLIB_H)
C_TREE_H = c-tree.h $(C_COMMON_H)
SYSTEM_H = system.h hwint.h $(srcdir)/../include/libiberty.h
PREDICT_H = predict.h predict.def
-CPPLIB_H = $(srcdir)/../libcpp/include/cpplib.h \
- $(srcdir)/../libcpp/include/line-map.h
+CPPLIB_H = $(srcdir)/../libcpp/include/line-map.h \
+ $(srcdir)/../libcpp/include/cpplib.h
MKDEPS_H = $(srcdir)/../libcpp/include/mkdeps.h
SYMTAB_H = $(srcdir)/../libcpp/include/symtab.h
+CPP_ID_DATA_H = $(CPPLIB_H) $(srcdir)/../libcpp/include/cpp-id-data.h
TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H)
TREE_GIMPLE_H = tree-gimple.h tree-iterator.h
TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \
@@ -1522,10 +1523,11 @@ dumpvers: dumpvers.c
version.o: version.c version.h
-gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) varray.h \
- $(HASHTAB_H) $(TREE_H) $(RTL_H) function.h insn-config.h $(EXPR_H) $(OPTABS_H) \
- libfuncs.h debug.h $(GGC_H) bitmap.h $(BASIC_BLOCK_H) hard-reg-set.h \
- cselib.h insn-addr.h $(TREE_FLOW_H)
+gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ varray.h $(HASHTAB_H) $(SPLAY_TREE_H) bitmap.h $(TREE_H) $(RTL_H) \
+ function.h insn-config.h $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) \
+ cselib.h insn-addr.h $(OPTABS_H) libfuncs.h debug.h $(GGC_H) \
+ cgraph.h tree-alias-type.h $(TREE_FLOW_H) reload.h $(CPP_ID_DATA_H)
ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \
$(HASHTAB_H) toplev.h $(PARAMS_H) hosthooks.h
@@ -2289,7 +2291,7 @@ s-preds: genpreds$(build_exeext)
$(STAMP) s-preds
GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h \
- $(srcdir)/../libcpp/include/cpplib.h $(host_xm_file_list) \
+ $(CPP_ID_DATA_H) $(host_xm_file_list) \
$(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) $(srcdir)/bitmap.h \
$(srcdir)/coverage.c $(srcdir)/function.h $(srcdir)/rtl.h \
$(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/libfuncs.h $(SYMTAB_H) \
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 804ef70320a..5d7082437b0 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -875,7 +875,7 @@ note_yacc_type (options_p o, pair_p fields, pair_p typeinfo,
}
static void process_gc_options (options_p, enum gc_used_enum,
- int *, int *, int *);
+ int *, int *, int *, type_p *);
static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
static void set_gc_used (pair_p);
@@ -883,7 +883,7 @@ static void set_gc_used (pair_p);
static void
process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
- int *pass_param, int *length)
+ int *pass_param, int *length, type_p *nested_ptr)
{
options_p o;
for (o = opt; o; o = o->next)
@@ -895,6 +895,8 @@ process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
*pass_param = 1;
else if (strcmp (o->name, "length") == 0)
*length = 1;
+ else if (strcmp (o->name, "nested_ptr") == 0)
+ *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
}
/* Set the gc_used field of T to LEVEL, and handle the types it references. */
@@ -914,18 +916,24 @@ set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
{
pair_p f;
int dummy;
+ type_p dummy2;
- process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy);
+ process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy,
+ &dummy2);
for (f = t->u.s.fields; f; f = f->next)
{
int maybe_undef = 0;
int pass_param = 0;
int length = 0;
+ type_p nested_ptr = NULL;
process_gc_options (f->opt, level, &maybe_undef, &pass_param,
- &length);
+ &length, &nested_ptr);
- if (length && f->type->kind == TYPE_POINTER)
+ if (nested_ptr && f->type->kind == TYPE_POINTER)
+ set_gc_used_type (nested_ptr, GC_POINTED_TO,
+ pass_param ? param : NULL);
+ else if (length && f->type->kind == TYPE_POINTER)
set_gc_used_type (f->type->u.p, GC_USED, NULL);
else if (maybe_undef && f->type->kind == TYPE_POINTER)
set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
@@ -1015,7 +1023,7 @@ static outf_p
create_file (const char *name, const char *oname)
{
static const char *const hdr[] = {
- " Copyright (C) 2003 Free Software Foundation, Inc.\n",
+ " Copyright (C) 2004 Free Software Foundation, Inc.\n",
"\n",
"This file is part of GCC.\n",
"\n",
@@ -1101,6 +1109,7 @@ open_base_files (void)
"basic-block.h", "cselib.h", "insn-addr.h", "optabs.h",
"libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
"tree-alias-type.h", "tree-flow.h", "reload.h",
+ "cpp-id-data.h",
NULL
};
const char *const *ifp;
@@ -1408,7 +1417,8 @@ struct walk_type_data
int used_length;
type_p orig_s;
const char *reorder_fn;
- int needs_cast_p;
+ bool needs_cast_p;
+ bool fn_wants_lvalue;
};
/* Print a mangled name representing T to OF. */
@@ -1511,7 +1521,7 @@ walk_type (type_p t, struct walk_type_data *d)
options_p oo;
const struct nested_ptr_data *nested_ptr_d = NULL;
- d->needs_cast_p = 0;
+ d->needs_cast_p = false;
for (oo = d->opt; oo; oo = oo->next)
if (strcmp (oo->name, "length") == 0)
length = (const char *)oo->info;
@@ -1525,7 +1535,7 @@ walk_type (type_p t, struct walk_type_data *d)
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 ;
+ nested_ptr_d = (const struct nested_ptr_data *) oo->info;
else if (strcmp (oo->name, "dot") == 0)
;
else if (strcmp (oo->name, "tag") == 0)
@@ -1643,10 +1653,12 @@ walk_type (type_p t, struct walk_type_data *d)
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, "",
+ oprintf (d->of, "%*s%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);
+ nested_ptr_d->type->u.s.tag,
+ d->fn_wants_lvalue ? "" : "const ",
+ d->val);
oprintf (d->of, "%*s", d->indent + 2, "");
output_escaped_param (d, nested_ptr_d->convert_from,
"nested_ptr");
@@ -1654,12 +1666,15 @@ walk_type (type_p t, struct walk_type_data *d)
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");
+ if (d->fn_wants_lvalue)
+ {
+ 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, "");
@@ -1839,6 +1854,7 @@ walk_type (type_p t, struct walk_type_data *d)
d->line = &f->line;
d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
d->opt = f->opt;
+ d->used_length = false;
if (union_p && use_param_p && d->param == NULL)
oprintf (d->of, "%*sabort();\n", d->indent, "");
@@ -2231,7 +2247,7 @@ write_types_local_process_field (type_p f, const struct walk_type_data *d)
/* For S, a structure that's part of ORIG_S, and using parameters
PARAM, write out a routine that:
- Is of type gt_note_pointers
- - If calls PROCESS_FIELD on each field of S or its substructures.
+ - Calls PROCESS_FIELD on each field of S or its substructures.
*/
static void
@@ -2259,6 +2275,7 @@ write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
d.prev_val[3] = "x";
d.val = "(*x)";
+ d.fn_wants_lvalue = true;
oprintf (d.of, "\n");
oprintf (d.of, "void\n");
diff --git a/gcc/stringpool.c b/gcc/stringpool.c
index d17f31decdd..0227688f6e1 100644
--- a/gcc/stringpool.c
+++ b/gcc/stringpool.c
@@ -51,7 +51,12 @@ static struct obstack string_stack;
static hashnode alloc_node (hash_table *);
static int mark_ident (struct cpp_reader *, hashnode, const void *);
-static int ht_copy_and_clear (struct cpp_reader *, hashnode, const void *);
+
+static void *
+stringpool_ggc_alloc (size_t x)
+{
+ return ggc_alloc (x);
+}
/* Initialize the string pool. */
void
@@ -60,6 +65,7 @@ init_stringpool (void)
/* Create with 16K (2^14) entries. */
ident_hash = ht_create (14);
ident_hash->alloc_node = alloc_node;
+ ident_hash->alloc_subobject = stringpool_ggc_alloc;
gcc_obstack_init (&string_stack);
}
@@ -212,39 +218,7 @@ struct string_pool_data GTY(())
static GTY(()) struct string_pool_data * spd;
-/* Copy HP into the corresponding entry in HT2, and then clear
- the cpplib parts of HP. */
-
-static int
-ht_copy_and_clear (cpp_reader *r ATTRIBUTE_UNUSED, hashnode hp, const void *ht2_p)
-{
- cpp_hashnode *h = CPP_HASHNODE (hp);
- struct ht *ht2 = (struct ht *) ht2_p;
-
- if (h->type != NT_VOID
- && (h->flags & NODE_BUILTIN) == 0)
- {
- cpp_hashnode *h2 = CPP_HASHNODE (ht_lookup (ht2,
- NODE_NAME (h),
- NODE_LEN (h),
- HT_ALLOC));
- h2->type = h->type;
- memcpy (&h2->value, &h->value, sizeof (h->value));
-
- h->type = NT_VOID;
- memset (&h->value, 0, sizeof (h->value));
- }
- return 1;
-}
-
-/* The hash table as it was before gt_pch_save_stringpool was called. */
-
-static struct ht *saved_ident_hash;
-
-/* 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. */
+/* Save the stringpool data in SPD. */
void
gt_pch_save_stringpool (void)
@@ -255,10 +229,6 @@ gt_pch_save_stringpool (void)
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;
- ht_forall (ident_hash, ht_copy_and_clear, saved_ident_hash);
}
/* Return the stringpool to its state before gt_pch_save_stringpool
@@ -267,9 +237,6 @@ gt_pch_save_stringpool (void)
void
gt_pch_fixup_stringpool (void)
{
- ht_forall (saved_ident_hash, ht_copy_and_clear, ident_hash);
- ht_destroy (saved_ident_hash);
- saved_ident_hash = 0;
}
/* A PCH file has been restored, which loaded SPD; fill the real hash table
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 332e3f0628b..c9565dd8949 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2004-06-09 Geoffrey Keating <geoffk@apple.com>
+
+ * gcc.dg/pch/macro-4.c: New.
+ * gcc.dg/pch/macro-4.hs: New.
+
2004-06-09 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
PR fortran/13249
diff --git a/gcc/testsuite/gcc.dg/pch/macro-4.c b/gcc/testsuite/gcc.dg/pch/macro-4.c
new file mode 100644
index 00000000000..1c199fa6eb0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/macro-4.c
@@ -0,0 +1,8 @@
+#define DEFN aa + bb
+
+#include "macro-4.h"
+
+int foo(int aa, int bb)
+{
+ return DEFN;
+}
diff --git a/gcc/testsuite/gcc.dg/pch/macro-4.hs b/gcc/testsuite/gcc.dg/pch/macro-4.hs
new file mode 100644
index 00000000000..5af162d63d1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/macro-4.hs
@@ -0,0 +1 @@
+/* No content! */
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index d81a049e646..cc2b9316887 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,27 @@
+2004-06-09 Geoffrey Keating <geoffk@apple.com>
+
+ * traditional.c (push_replacement_text): Set macro->traditional.
+ (save_replacement_text): Likewise.
+ * pch.c (cpp_write_pch_state): Don't write list of defined macros.
+ (struct save_macro_item): Delete.
+ (struct save_macro_data): Use a character array not the previous
+ structured format.
+ (save_macros): Save macro as text not as internal structures.
+ (cpp_prepare_state): Update for changes to save_macro_data.
+ (cpp_read_state): Don't read macros defined in PCH. Restore
+ -D macros as text.
+ * macro.c (create_iso_definition): Honour alloc_subobject.
+ Clear traditional flag.
+ (_cpp_create_definition): Honour alloc_subobject.
+ * lex.c (cpp_token_val_index): New.
+ * internal.h: Include cpp-id-data.h.
+ (uchar): Move definition to cpp-id-data.h.
+ (U): Likewise.
+ (cpp_macro): Likewise.
+ * directives.c (struct answer): Move to cpp-id-data.h.
+ (do_assert): Honour alloc_subobject.
+
+
2004-06-09 Paolo Bonzini <bonzini@gnu.org>
* Makefile.am (all-local): New.
diff --git a/libcpp/directives.c b/libcpp/directives.c
index 5a6a342bea5..16873dadecf 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -26,14 +26,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "mkdeps.h"
#include "obstack.h"
-/* Chained list of answers to an assertion. */
-struct answer
-{
- struct answer *next;
- unsigned int count;
- cpp_token first[1];
-};
-
/* Stack of conditionals currently in progress
(including both successful and failing conditionals). */
struct if_stack
@@ -1727,6 +1719,8 @@ do_assert (cpp_reader *pfile)
node = parse_assertion (pfile, &new_answer, T_ASSERT);
if (node)
{
+ size_t answer_size;
+
/* Place the new answer in the answer list. First check there
is not a duplicate. */
new_answer->next = 0;
@@ -1741,11 +1735,20 @@ do_assert (cpp_reader *pfile)
new_answer->next = node->value.answers;
}
+ answer_size = sizeof (struct answer) + ((new_answer->count - 1)
+ * sizeof (cpp_token));
+ /* Commit or allocate storage for the object. */
+ if (pfile->hash_table->alloc_subobject)
+ {
+ struct answer *temp_answer = new_answer;
+ new_answer = pfile->hash_table->alloc_subobject (answer_size);
+ memcpy (new_answer, temp_answer, answer_size);
+ }
+ else
+ BUFF_FRONT (pfile->a_buff) += answer_size;
+
node->type = NT_ASSERTION;
node->value.answers = new_answer;
- BUFF_FRONT (pfile->a_buff) += (sizeof (struct answer)
- + (new_answer->count - 1)
- * sizeof (cpp_token));
check_eol (pfile);
}
}
diff --git a/libcpp/include/ChangeLog b/libcpp/include/ChangeLog
index a2f4bc5e3ef..0dbd0c33474 100644
--- a/libcpp/include/ChangeLog
+++ b/libcpp/include/ChangeLog
@@ -1,3 +1,14 @@
+2004-06-09 Geoffrey Keating <geoffk@apple.com>
+
+ * symtab.h (struct ht): Add field 'alloc_subobject'.
+ * cpplib.h (struct cpp_string): Add GTY marker.
+ (enum cpp_token_fld_kind): New.
+ (struct cpp_token): Add GTY markers.
+ (cpp_token_val_index): Prototype.
+ (CPP_HASHNODE_VALUE_IDX): New.
+ (struct cpp_hashnode): Don't skip fields of 'value' when marking.
+ * cpp-id-data.h: New file.
+
2004-05-29 Geoffrey Keating <geoffk@apple.com>
* symtab.h (struct ht): New field 'entries_owned'
diff --git a/libcpp/include/cpp-id-data.h b/libcpp/include/cpp-id-data.h
new file mode 100644
index 00000000000..bdeaeba5182
--- /dev/null
+++ b/libcpp/include/cpp-id-data.h
@@ -0,0 +1,77 @@
+/* Structures that hang off cpp_identifier, for PCH.
+ Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 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
+Free Software Foundation; either version 2, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "cpplib.h"
+
+#ifndef HAVE_UCHAR
+typedef unsigned char uchar;
+#endif
+#define U (const uchar *) /* Intended use: U"string" */
+
+/* Chained list of answers to an assertion. */
+struct answer GTY(())
+{
+ struct answer *next;
+ unsigned int count;
+ cpp_token GTY ((length ("%h.count"))) first[1];
+};
+
+/* Each macro definition is recorded in a cpp_macro structure.
+ Variadic macros cannot occur with traditional cpp. */
+struct cpp_macro GTY(())
+{
+ /* Parameters, if any. */
+ cpp_hashnode ** GTY ((nested_ptr (union tree_node,
+ "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL",
+ "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL"),
+ length ("%h.paramc")))
+ params;
+
+ /* Replacement tokens (ISO) or replacement text (traditional). See
+ comment at top of cpptrad.c for how traditional function-like
+ macros are encoded. */
+ union cpp_macro_u
+ {
+ cpp_token * GTY ((tag ("0"), length ("%0.count"))) tokens;
+ const uchar * GTY ((tag ("1"))) text;
+ } GTY ((desc ("%1.traditional"))) exp;
+
+ /* Definition line number. */
+ source_location line;
+
+ /* Number of tokens in expansion, or bytes for traditional macros. */
+ unsigned int count;
+
+ /* Number of parameters. */
+ unsigned short paramc;
+
+ /* If a function-like macro. */
+ unsigned int fun_like : 1;
+
+ /* If a variadic macro. */
+ unsigned int variadic : 1;
+
+ /* If macro defined in system header. */
+ unsigned int syshdr : 1;
+
+ /* Nonzero if it has been expanded or had its existence tested. */
+ unsigned int used : 1;
+
+ /* Indicate which field of 'exp' is in use. */
+ unsigned int traditional : 1;
+};
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index cf701b5e861..dab315714df 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -156,7 +156,7 @@ enum c_lang {CLK_GNUC89 = 0, CLK_GNUC99, CLK_STDC89, CLK_STDC94, CLK_STDC99,
CLK_GNUCXX, CLK_CXX98, CLK_ASM};
/* Payload of a NUMBER, STRING, CHAR or COMMENT token. */
-struct cpp_string
+struct cpp_string GTY(())
{
unsigned int len;
const unsigned char *text;
@@ -171,23 +171,48 @@ struct cpp_string
#define NO_EXPAND (1 << 5) /* Do not macro-expand this token. */
#define BOL (1 << 6) /* Token at beginning of line. */
+/* Specify which field, if any, of the cpp_token union is used. */
+
+enum cpp_token_fld_kind {
+ CPP_TOKEN_FLD_NODE,
+ CPP_TOKEN_FLD_SOURCE,
+ CPP_TOKEN_FLD_STR,
+ CPP_TOKEN_FLD_ARG_NO,
+ CPP_TOKEN_FLD_NONE
+};
+
/* A preprocessing token. This has been carefully packed and should
occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */
-struct cpp_token
+struct cpp_token GTY(())
{
source_location src_loc; /* Location of first char of token. */
ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */
unsigned char flags; /* flags - see above */
- union
+ union cpp_token_u
{
- cpp_hashnode *node; /* An identifier. */
- const cpp_token *source; /* Inherit padding from this token. */
- struct cpp_string str; /* A string, or number. */
- unsigned int arg_no; /* Argument no. for a CPP_MACRO_ARG. */
- } val;
+ /* An identifier. */
+ cpp_hashnode *
+ GTY ((nested_ptr (union tree_node,
+ "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL",
+ "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL"),
+ tag ("CPP_TOKEN_FLD_NODE")))
+ node;
+
+ /* Inherit padding from this token. */
+ cpp_token * GTY ((tag ("CPP_TOKEN_FLD_SOURCE"))) source;
+
+ /* A string, or number. */
+ struct cpp_string GTY ((tag ("CPP_TOKEN_FLD_STR"))) str;
+
+ /* Argument no. for a CPP_MACRO_ARG. */
+ unsigned int GTY ((tag ("CPP_TOKEN_FLD_ARG_NO"))) arg_no;
+ } GTY ((desc ("cpp_token_val_index (&%1)"))) val;
};
+/* Say which field is in use. */
+extern enum cpp_token_fld_kind cpp_token_val_index (cpp_token *tok);
+
/* A type wide enough to hold any multibyte source character.
cpplib's character constant interpreter requires an unsigned type.
Also, a typedef for the signed equivalent.
@@ -498,6 +523,23 @@ enum builtin_type
#define NODE_LEN(NODE) HT_LEN (&(NODE)->ident)
#define NODE_NAME(NODE) HT_STR (&(NODE)->ident)
+/* Specify which field, if any, of the union is used. */
+
+enum {
+ NTV_MACRO,
+ NTV_ANSWER,
+ NTV_BUILTIN,
+ NTV_ARGUMENT,
+ NTV_NONE
+};
+
+#define CPP_HASHNODE_VALUE_IDX(HNODE) \
+ ((HNODE.flags & NODE_MACRO_ARG) ? NTV_ARGUMENT \
+ : HNODE.type == NT_MACRO ? ((HNODE.flags & NODE_BUILTIN) \
+ ? NTV_BUILTIN : NTV_MACRO) \
+ : HNODE.type == NT_ASSERTION ? NTV_ANSWER \
+ : NTV_NONE)
+
/* The common part of an identifier node shared amongst all 3 C front
ends. Also used to store CPP identifiers, which are a superset of
identifiers in the grammatical sense. */
@@ -515,14 +557,14 @@ struct cpp_hashnode GTY(())
union _cpp_hashnode_value
{
/* If a macro. */
- cpp_macro * GTY((skip)) macro;
+ cpp_macro * GTY((tag ("NTV_MACRO"))) macro;
/* Answers to an assertion. */
- struct answer * GTY ((skip)) answers;
+ struct answer * GTY ((tag ("NTV_ANSWER"))) answers;
/* Code for a builtin macro. */
- enum builtin_type GTY ((tag ("1"))) builtin;
+ enum builtin_type GTY ((tag ("NTV_BUILTIN"))) builtin;
/* Macro argument index. */
- unsigned short GTY ((tag ("0"))) arg_index;
- } GTY ((desc ("0"))) value;
+ unsigned short GTY ((tag ("NTV_ARGUMENT"))) arg_index;
+ } GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value;
};
/* Call this first to get a handle to pass to other functions.
diff --git a/libcpp/include/symtab.h b/libcpp/include/symtab.h
index d11e4efe6dc..0b2a848739e 100644
--- a/libcpp/include/symtab.h
+++ b/libcpp/include/symtab.h
@@ -46,8 +46,11 @@ struct ht
struct obstack stack;
hashnode *entries;
- /* Call back. */
+ /* Call back, allocate a node. */
hashnode (*alloc_node) (hash_table *);
+ /* Call back, allocate something that hangs off a node like a cpp_macro.
+ NULL means use the usual allocator. */
+ void * (*alloc_subobject) (size_t);
unsigned int nslots; /* Total slots in the entries array. */
unsigned int nelements; /* Number of live elements. */
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 3608201d560..fd3facf6136 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -24,6 +24,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define LIBCPP_INTERNAL_H
#include "symtab.h"
+#include "cpp-id-data.h"
#if defined HAVE_ICONV_H && defined HAVE_ICONV
#include <iconv.h>
@@ -45,11 +46,6 @@ struct cset_converter
iconv_t cd;
};
-#ifndef HAVE_UCHAR
-typedef unsigned char uchar;
-#endif
-#define U (const uchar *) /* Intended use: U"string" */
-
#define BITS_PER_CPPCHAR_T (CHAR_BIT * sizeof (cppchar_t))
/* Test if a sign is valid within a preprocessing number. */
@@ -90,44 +86,6 @@ struct dummy
#define CPP_ALIGN2(size, align) (((size) + ((align) - 1)) & ~((align) - 1))
#define CPP_ALIGN(size) CPP_ALIGN2 (size, DEFAULT_ALIGNMENT)
-/* Each macro definition is recorded in a cpp_macro structure.
- Variadic macros cannot occur with traditional cpp. */
-struct cpp_macro
-{
- /* Parameters, if any. */
- cpp_hashnode **params;
-
- /* Replacement tokens (ISO) or replacement text (traditional). See
- comment at top of cpptrad.c for how traditional function-like
- macros are encoded. */
- union
- {
- cpp_token *tokens;
- const uchar *text;
- } exp;
-
- /* Definition line number. */
- fileline line;
-
- /* Number of tokens in expansion, or bytes for traditional macros. */
- unsigned int count;
-
- /* Number of parameters. */
- unsigned short paramc;
-
- /* If a function-like macro. */
- unsigned int fun_like : 1;
-
- /* If a variadic macro. */
- unsigned int variadic : 1;
-
- /* If macro defined in system header. */
- unsigned int syshdr : 1;
-
- /* Nonzero if it has been expanded or had its existence tested. */
- unsigned int used : 1;
-};
-
#define _cpp_mark_macro_used(NODE) do { \
if ((NODE)->type == NT_MACRO && !((NODE)->flags & NODE_BUILTIN)) \
(NODE)->value.macro->used = 1; } while (0)
diff --git a/libcpp/lex.c b/libcpp/lex.c
index 37df6efc0b7..7eafb13d3b4 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -1556,3 +1556,25 @@ _cpp_aligned_alloc (cpp_reader *pfile, size_t len)
buff->cur = result + len;
return result;
}
+
+/* Say which field of TOK is in use. */
+
+enum cpp_token_fld_kind
+cpp_token_val_index (cpp_token *tok)
+{
+ switch (TOKEN_SPELL (tok))
+ {
+ case SPELL_IDENT:
+ return CPP_TOKEN_FLD_NODE;
+ case SPELL_LITERAL:
+ return CPP_TOKEN_FLD_STR;
+ case SPELL_NONE:
+ if (tok->type == CPP_MACRO_ARG)
+ return CPP_TOKEN_FLD_ARG_NO;
+ else if (tok->type == CPP_PADDING)
+ return CPP_TOKEN_FLD_SOURCE;
+ /* else fall through */
+ default:
+ return CPP_TOKEN_FLD_NONE;
+ }
+}
diff --git a/libcpp/macro.c b/libcpp/macro.c
index cfc42b4050f..dc58b3180f1 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -1408,8 +1408,16 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
if (!ok)
return false;
- /* Success. Commit the parameter array. */
- BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
+ /* Success. Commit or allocate the parameter array. */
+ if (pfile->hash_table->alloc_subobject)
+ {
+ cpp_token *tokns = pfile->hash_table->alloc_subobject
+ (sizeof (cpp_token) * macro->paramc);
+ memcpy (tokns, macro->params, sizeof (cpp_token) * macro->paramc);
+ macro->params = tokns;
+ }
+ else
+ BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
macro->fun_like = 1;
}
else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE))
@@ -1472,6 +1480,7 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
}
macro->exp.tokens = (cpp_token *) BUFF_FRONT (pfile->a_buff);
+ macro->traditional = 0;
/* Don't count the CPP_EOF. */
macro->count--;
@@ -1480,8 +1489,16 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
if (macro->count)
macro->exp.tokens[0].flags &= ~PREV_WHITE;
- /* Commit the memory. */
- BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->exp.tokens[macro->count];
+ /* Commit or allocate the memory. */
+ if (pfile->hash_table->alloc_subobject)
+ {
+ cpp_token *tokns = pfile->hash_table->alloc_subobject (sizeof (cpp_token)
+ * macro->count);
+ memcpy (tokns, macro->exp.tokens, sizeof (cpp_token) * macro->count);
+ macro->exp.tokens = tokns;
+ }
+ else
+ BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->exp.tokens[macro->count];
return true;
}
@@ -1494,7 +1511,10 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
unsigned int i;
bool ok;
- macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro));
+ if (pfile->hash_table->alloc_subobject)
+ macro = pfile->hash_table->alloc_subobject (sizeof (cpp_macro));
+ else
+ macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro));
macro->line = pfile->directive_line;
macro->params = 0;
macro->paramc = 0;
diff --git a/libcpp/pch.c b/libcpp/pch.c
index 51175a9a67b..a9d139a30b7 100644
--- a/libcpp/pch.c
+++ b/libcpp/pch.c
@@ -347,15 +347,6 @@ cpp_write_pch_state (cpp_reader *r, FILE *f)
{
struct macrodef_struct z;
- /* Write out the list of defined identifiers. */
- cpp_forall_identifiers (r, write_macdef, f);
- memset (&z, 0, sizeof (z));
- if (fwrite (&z, sizeof (z), 1, f) != 1)
- {
- cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
- return -1;
- }
-
if (!r->deps)
r->deps = deps_init ();
@@ -544,46 +535,64 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
return 1;
}
-/* Save all the existing macros and assertions.
- This code assumes that there might be hundreds, but not thousands of
- existing definitions. */
-
-struct save_macro_item {
- struct save_macro_item *next;
- struct cpp_hashnode macs[64];
-};
+/* Save all the existing macros. */
struct save_macro_data
{
- struct save_macro_item *macros;
+ uchar **defns;
size_t count;
+ size_t array_size;
char **saved_pragmas;
};
-/* Save the definition of a single macro, so that it will persist across
- a PCH restore. */
+/* Save the definition of a single macro, so that it will persist
+ across a PCH restore. Because macro data is in GCed memory, which
+ will be blown away by PCH, it must be temporarily copied to
+ malloced memory. (The macros will refer to identifier nodes which
+ are also GCed and so on, so the copying is done by turning them
+ into self-contained strings.) The assumption is that most macro
+ definitions will come from the PCH file, not from the compilation
+ before the PCH file is loaded, so it doesn't matter that this is
+ a little expensive.
+
+ It would reduce the cost even further if macros defined in the PCH
+ file were not saved in this way, but this is not done (yet), except
+ for builtins, and for #assert by default. */
static int
-save_macros (cpp_reader *r ATTRIBUTE_UNUSED, cpp_hashnode *h, void *data_p)
+save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p)
{
struct save_macro_data *data = (struct save_macro_data *)data_p;
if (h->type != NT_VOID
&& (h->flags & NODE_BUILTIN) == 0)
{
- cpp_hashnode *save;
- if (data->count == ARRAY_SIZE (data->macros->macs))
+ if (data->count == data->array_size)
+ {
+ data->array_size *= 2;
+ data->defns = xrealloc (data->defns, (data->array_size
+ * sizeof (uchar *)));
+ }
+
+ switch (h->type)
{
- struct save_macro_item *d = data->macros;
- data->macros = xmalloc (sizeof (struct save_macro_item));
- data->macros->next = d;
- data->count = 0;
+ case NT_ASSERTION:
+ /* Not currently implemented. */
+ return 1;
+
+ case NT_MACRO:
+ {
+ const uchar * defn = cpp_macro_definition (r, h);
+ size_t defnlen = ustrlen (defn);
+
+ data->defns[data->count] = xmemdup (defn, defnlen, defnlen + 2);
+ data->defns[data->count][defnlen] = '\n';
+ }
+ break;
+
+ default:
+ abort ();
}
- save = data->macros->macs + data->count;
data->count++;
- memcpy (save, h, sizeof (struct cpp_hashnode));
- HT_STR (&save->ident) = xmemdup (HT_STR (HT_NODE (save)),
- HT_LEN (HT_NODE (save)),
- HT_LEN (HT_NODE (save)) + 1);
}
return 1;
}
@@ -596,8 +605,9 @@ cpp_prepare_state (cpp_reader *r, struct save_macro_data **data)
{
struct save_macro_data *d = xmalloc (sizeof (struct save_macro_data));
- d->macros = NULL;
- d->count = ARRAY_SIZE (d->macros->macs);
+ d->array_size = 512;
+ d->defns = xmalloc (d->array_size * sizeof (d->defns[0]));
+ d->count = 0;
cpp_forall_identifiers (r, save_macros, d);
d->saved_pragmas = _cpp_save_pragma_names (r);
*data = d;
@@ -612,11 +622,9 @@ cpp_read_state (cpp_reader *r, const char *name, FILE *f,
struct save_macro_data *data)
{
struct macrodef_struct m;
- size_t defnlen = 256;
- unsigned char *defn = xmalloc (defnlen);
- struct lexer_state old_state;
struct save_macro_item *d;
size_t i, mac_count;
+ struct lexer_state old_state;
/* Restore spec_nodes, which will be full of references to the old
hashtable entries and so will now be invalid. */
@@ -628,70 +636,28 @@ cpp_read_state (cpp_reader *r, const char *name, FILE *f,
s->n__VA_ARGS__ = cpp_lookup (r, DSC("__VA_ARGS__"));
}
- /* Run through the carefully-saved macros, insert them. */
- d = data->macros;
- mac_count = data->count;
- while (d)
- {
- struct save_macro_item *nextd;
- for (i = 0; i < mac_count; i++)
- {
- cpp_hashnode *h;
-
- h = cpp_lookup (r, HT_STR (HT_NODE (&d->macs[i])),
- HT_LEN (HT_NODE (&d->macs[i])));
- h->type = d->macs[i].type;
- h->flags = d->macs[i].flags;
- h->value = d->macs[i].value;
- free ((void *)HT_STR (HT_NODE (&d->macs[i])));
- }
- nextd = d->next;
- free (d);
- d = nextd;
- mac_count = ARRAY_SIZE (d->macs);
- }
-
- _cpp_restore_pragma_names (r, data->saved_pragmas);
-
- free (data);
-
old_state = r->state;
-
r->state.in_directive = 1;
r->state.prevent_expansion = 1;
r->state.angled_headers = 0;
- /* Read in the identifiers that must be defined. */
- for (;;)
+ /* Run through the carefully-saved macros, insert them. */
+ for (i = 0; i < data->count; i++)
{
cpp_hashnode *h;
-
- if (fread (&m, sizeof (m), 1, f) != 1)
- goto error;
-
- if (m.name_length == 0)
- break;
-
- if (defnlen < m.definition_length + 1)
- {
- defnlen = m.definition_length + 256;
- defn = xrealloc (defn, defnlen);
- }
+ size_t namelen;
+ uchar *defn;
- if (fread (defn, 1, m.definition_length, f) != m.definition_length)
- goto error;
- defn[m.definition_length] = '\n';
-
- h = cpp_lookup (r, defn, m.name_length);
+ namelen = strcspn (data->defns[i], "( \n");
+ h = cpp_lookup (r, data->defns[i], namelen);
+ defn = data->defns[i] + namelen;
- if (h->type == NT_MACRO)
- _cpp_free_definition (h);
- if (m.flags & NODE_POISONED)
- h->flags |= NODE_POISONED | NODE_DIAGNOSTIC;
- else if (m.name_length != m.definition_length)
+ /* The PCH file is valid, so we know that if there is a definition
+ from the PCH file it must be the same as the one we had
+ originally, and so do not need to restore it. */
+ if (h->type == NT_VOID)
{
- if (cpp_push_buffer (r, defn + m.name_length,
- m.definition_length - m.name_length, true)
+ if (cpp_push_buffer (r, defn, ustrchr (defn, '\n') - defn, true)
!= NULL)
{
_cpp_clean_line (r);
@@ -702,11 +668,14 @@ cpp_read_state (cpp_reader *r, const char *name, FILE *f,
else
abort ();
}
- }
+ free (data->defns[i]);
+ }
r->state = old_state;
- free (defn);
- defn = NULL;
+
+ _cpp_restore_pragma_names (r, data->saved_pragmas);
+
+ free (data);
if (deps_restore (r->deps, f, CPP_OPTION (r, restore_pch_deps) ? name : NULL)
!= 0)
diff --git a/libcpp/traditional.c b/libcpp/traditional.c
index f4ce9f66e47..38e301c43ff 100644
--- a/libcpp/traditional.c
+++ b/libcpp/traditional.c
@@ -701,6 +701,7 @@ push_replacement_text (cpp_reader *pfile, cpp_hashnode *node)
cpp_macro *macro = node->value.macro;
macro->used = 1;
text = macro->exp.text;
+ macro->traditional = 1;
len = macro->count;
}
@@ -934,6 +935,7 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro,
memcpy (exp, pfile->out.base, len);
exp[len] = '\n';
macro->exp.text = exp;
+ macro->traditional = 1;
macro->count = len;
}
else
@@ -949,6 +951,7 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro,
exp = BUFF_FRONT (pfile->a_buff);
block = (struct block *) (exp + macro->count);
macro->exp.text = exp;
+ macro->traditional = 1;
/* Write out the block information. */
block->text_len = len;