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.

From-SVN: r82851
This commit is contained in:
Geoffrey Keating 2004-06-09 20:10:13 +00:00 committed by Geoffrey Keating
parent 293155b099
commit d8044160b7
18 changed files with 373 additions and 234 deletions

View File

@ -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:

View File

@ -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) \

View File

@ -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");

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,8 @@
#define DEFN aa + bb
#include "macro-4.h"
int foo(int aa, int bb)
{
return DEFN;
}

View File

@ -0,0 +1 @@
/* No content! */

View File

@ -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.

View File

@ -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);
}
}

View File

@ -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'

View File

@ -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;
};

View File

@ -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.

View File

@ -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. */

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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)
{
struct save_macro_item *d = data->macros;
data->macros = xmalloc (sizeof (struct save_macro_item));
data->macros->next = d;
data->count = 0;
data->array_size *= 2;
data->defns = xrealloc (data->defns, (data->array_size
* sizeof (uchar *)));
}
switch (h->type)
{
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;
size_t namelen;
uchar *defn;
if (defnlen < m.definition_length + 1)
namelen = strcspn (data->defns[i], "( \n");
h = cpp_lookup (r, data->defns[i], namelen);
defn = data->defns[i] + namelen;
/* 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)
{
defnlen = m.definition_length + 256;
defn = xrealloc (defn, defnlen);
}
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);
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)
{
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)

View File

@ -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;