diff options
author | geoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-09 20:10:13 +0000 |
---|---|---|
committer | geoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-09 20:10:13 +0000 |
commit | c39ed964c8cd9aec2fe6060830804416b0856b60 (patch) | |
tree | 1238be7fc80d74d8323d5f6c4344a6bb2be0f854 /libcpp | |
parent | f5efe504032463d907b2eb0f4f76a5d68ce45429 (diff) | |
download | gcc-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/ChangeLog | 24 | ||||
-rw-r--r-- | libcpp/directives.c | 25 | ||||
-rw-r--r-- | libcpp/include/ChangeLog | 11 | ||||
-rw-r--r-- | libcpp/include/cpp-id-data.h | 77 | ||||
-rw-r--r-- | libcpp/include/cpplib.h | 68 | ||||
-rw-r--r-- | libcpp/include/symtab.h | 5 | ||||
-rw-r--r-- | libcpp/internal.h | 44 | ||||
-rw-r--r-- | libcpp/lex.c | 22 | ||||
-rw-r--r-- | libcpp/macro.c | 30 | ||||
-rw-r--r-- | libcpp/pch.c | 157 | ||||
-rw-r--r-- | libcpp/traditional.c | 3 |
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 *) ¯o->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 *) ¯o->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 *) ¯o->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 *) ¯o->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; |