/* Part of CPP library. (Precompiled header reading/writing.)
- Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+ 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
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. */
+Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include "config.h"
#include "system.h"
struct cpp_string *sp;
unsigned char *text;
- sp = xmalloc (sizeof (struct cpp_string));
+ sp = XNEW (struct cpp_string);
*slot = sp;
sp->len = NODE_LEN (hn);
- sp->text = text = xmalloc (NODE_LEN (hn));
+ sp->text = text = XNEWVEC (unsigned char, NODE_LEN (hn));
memcpy (text, NODE_NAME (hn), NODE_LEN (hn));
}
}
cpp_save_state (cpp_reader *r, FILE *f)
{
/* Save the list of non-void identifiers for the dependency checking. */
- r->savedstate = xmalloc (sizeof (struct cpp_savedstate));
+ r->savedstate = XNEW (struct cpp_savedstate);
r->savedstate->definedhash = htab_create (100, cpp_string_hash,
cpp_string_eq, NULL);
cpp_forall_identifiers (r, save_idents, r->savedstate);
news.len = NODE_LEN (hn);
news.text = NODE_NAME (hn);
- slot = htab_find (ss->definedhash, &news);
+ slot = (void **) htab_find (ss->definedhash, &news);
if (slot == NULL)
{
ss->hashsize += NODE_LEN (hn) + 1;
news.len = NODE_LEN (hn);
news.text = NODE_NAME (hn);
- slot = htab_find (ss->definedhash, &news);
+ slot = (void **) htab_find (ss->definedhash, &news);
if (slot == NULL)
{
ss->defs[ss->n_defs] = hn;
ss->n_defs = 0;
cpp_forall_identifiers (r, count_defs, ss);
- ss->defs = xmalloc (ss->n_defs * sizeof (cpp_hashnode *));
+ ss->defs = XNEWVEC (cpp_hashnode *, ss->n_defs);
ss->n_defs = 0;
cpp_forall_identifiers (r, write_defs, ss);
/* Sort the list, copy it into a buffer, and write it out. */
qsort (ss->defs, ss->n_defs, sizeof (cpp_hashnode *), &comp_hashnodes);
- definedstrs = ss->definedstrs = xmalloc (ss->hashsize);
+ definedstrs = ss->definedstrs = XNEWVEC (unsigned char, ss->hashsize);
for (i = 0; i < ss->n_defs; ++i)
{
size_t len = NODE_LEN (ss->defs[i]);
int
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 ();
if (nl->n_defs == nl->asize)
{
nl->asize *= 2;
- nl->defs = xrealloc (nl->defs, nl->asize * sizeof (cpp_hashnode *));
+ nl->defs = XRESIZEVEC (cpp_hashnode *, nl->defs, nl->asize);
}
nl->defs[nl->n_defs] = hn;
{
struct macrodef_struct m;
size_t namebufsz = 256;
- unsigned char *namebuf = xmalloc (namebufsz);
+ unsigned char *namebuf = XNEWVEC (unsigned char, namebufsz);
unsigned char *undeftab = NULL;
struct ht_node_list nl = { 0, 0, 0 };
unsigned char *first, *last;
if (m.name_length == 0)
break;
+ /* If this file is already preprocessed, there won't be any
+ macros defined, and that's OK. */
+ if (CPP_OPTION (r, preprocessed))
+ {
+ if (lseek (fd, m.definition_length, SEEK_CUR) == -1)
+ goto error;
+ continue;
+ }
+
if (m.definition_length > namebufsz)
{
free (namebuf);
namebufsz = m.definition_length + 256;
- namebuf = xmalloc (namebufsz);
+ namebuf = XNEWVEC (unsigned char, namebufsz);
}
-
+
if ((size_t)read (fd, namebuf, m.definition_length)
!= m.definition_length)
goto error;
/* Read in the list of identifiers that must not be defined.
Check that they really aren't. */
- undeftab = xmalloc (m.definition_length);
+ undeftab = XNEWVEC (unsigned char, m.definition_length);
if ((size_t) read (fd, undeftab, m.definition_length) != m.definition_length)
goto error;
/* Collect identifiers from the current hash table. */
nl.n_defs = 0;
nl.asize = 10;
- nl.defs = xmalloc (nl.asize * sizeof (cpp_hashnode *));
+ nl.defs = XNEWVEC (cpp_hashnode *, nl.asize);
cpp_forall_identifiers (r, &collect_ht_nodes, &nl);
qsort (nl.defs, nl.n_defs, sizeof (cpp_hashnode *), &comp_hashnodes);
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 = XRESIZEVEC (uchar *, data->defns, (data->array_size));
+ }
+
+ 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] = (uchar *) 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;
}
void
cpp_prepare_state (cpp_reader *r, struct save_macro_data **data)
{
- struct save_macro_data *d = xmalloc (sizeof (struct save_macro_data));
+ struct save_macro_data *d = XNEW (struct save_macro_data);
- d->macros = NULL;
- d->count = ARRAY_SIZE (d->macros->macs);
+ d->array_size = 512;
+ d->defns = XNEWVEC (uchar *, d->array_size);
+ d->count = 0;
cpp_forall_identifiers (r, save_macros, d);
d->saved_pragmas = _cpp_save_pragma_names (r);
*data = d;
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);
+ size_t i;
struct lexer_state old_state;
- struct save_macro_item *d;
- size_t i, mac_count;
/* Restore spec_nodes, which will be full of references to the old
hashtable entries and so will now be invalid. */
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)
- {
- 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);
+ namelen = ustrcspn (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);
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)