summaryrefslogtreecommitdiff
path: root/libcpp
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 /libcpp
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
Diffstat (limited to 'libcpp')
-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
11 files changed, 299 insertions, 167 deletions
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;