aboutsummaryrefslogtreecommitdiff
path: root/libcpp/pch.c
diff options
context:
space:
mode:
authorKai Tietz <kai.tietz@onevision.com>2009-11-11 18:37:19 +0000
committerKai Tietz <ktietz@gcc.gnu.org>2009-11-11 19:37:19 +0100
commit17e7cb855000baa6598005571d7dd49cfac5282a (patch)
treee54ead3691775dbb1e9d31588966d79cac024672 /libcpp/pch.c
parent110532c838d2302c88de13ad88f81ec975ed4b1e (diff)
downloadgcc-17e7cb855000baa6598005571d7dd49cfac5282a.zip
gcc-17e7cb855000baa6598005571d7dd49cfac5282a.tar.gz
gcc-17e7cb855000baa6598005571d7dd49cfac5282a.tar.bz2
ChangeLog for libcpp
2009-11-11 Kai Tietz <kai.tietz@onevision.com> * directives.c (do_pragma_push_macro): New pragma handler. (do_pragma_pop_macro): Likewise. (_cpp_init_internal_pragmas): Add push_macro and pop_macro handler to internal pragmas. (lex_macro_node_from_str): Removed. (cpp_push_definition): Replace lex_macro_node_from_str by _cpp_lex_identifier. (cpp_pop_definition): Likewise. * internal.h (_cpp_lex_identifier): New prototype. (def_pragma_macro): New structure. (cpp_reader): New member pushed_macros. * lex.c (_cpp_lex_identifier): New function. (lex_identifier_intern): New function. * init.c (cpp_create_reader): Initialize pushed_macros member. (cpp_destroy): Free elements in pushed_macros member. * pch.c (_cpp_save_pushed_macros): New function. (_cpp_restore_pushed_macros): Likewise. (_cpp_restore_pushed_macros): Use _cpp_save_pushed_macros. (cpp_read_state): Use _cpp_restore_pushed_macros. ChangeLog for gcc 2009-11-11 Kai Tietz <kai.tietz@onevision.com> * config/i386/cygming.h (HANDLE_PRAGMA_PUSH_POP_MACRO): Removed. * c-pragma.c (def_pragma_macro_value): Likewise. (def_pragma_macro): Likewise. (pushed_macro_table): Likewise. (HANDLE_PRAGMA_PUSH_POP_MACRO): Remove guarded code. * doc/tm.texi (HANDLE_PRAGMA_PUSH_POP_MACRO): Removed. ChangeLog for gcc/testsuite 2009-11-11 Kai Tietz <kai.tietz@onevision.com> * g++.dg/torture/pushpop_macro.C: New testcase. * gcc.c-torture/execute/pushpop_macro.c: New testcase. * gcc.dg/cpp/pragma-pop_macro-1.c: Allow test for all targets. From-SVN: r154098
Diffstat (limited to 'libcpp/pch.c')
-rw-r--r--libcpp/pch.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/libcpp/pch.c b/libcpp/pch.c
index f656418..c70759a 100644
--- a/libcpp/pch.c
+++ b/libcpp/pch.c
@@ -33,6 +33,8 @@ static int comp_hashnodes (const void *, const void *);
static int collect_ht_nodes (cpp_reader *, cpp_hashnode *, void *);
static int write_defs (cpp_reader *, cpp_hashnode *, void *);
static int save_macros (cpp_reader *, cpp_hashnode *, void *);
+static int _cpp_save_pushed_macros (cpp_reader *, FILE *);
+static int _cpp_restore_pushed_macros (cpp_reader *, FILE *);
/* This structure represents a macro definition on disk. */
struct macrodef_struct
@@ -378,9 +380,140 @@ cpp_write_pch_state (cpp_reader *r, FILE *f)
return -1;
}
+ /* Write saved macros. */
+ if (! _cpp_save_pushed_macros (r, f))
+ {
+ cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
+ return -1;
+ }
+
return 0;
}
+static int
+_cpp_restore_pushed_macros (cpp_reader *r, FILE *f)
+{
+ size_t count_saved = 0;
+ size_t i;
+ struct def_pragma_macro *p;
+ size_t nlen;
+ cpp_hashnode *h = NULL;
+ cpp_macro *m;
+ uchar *defn;
+ size_t defnlen;
+
+ if (fread (&count_saved, sizeof (count_saved), 1, f) != 1)
+ return 0;
+ if (! count_saved)
+ return 1;
+ for (i = 0; i < count_saved; i++)
+ {
+ if (fread (&nlen, sizeof (nlen), 1, f) != 1)
+ return 0;
+ p = XNEW (struct def_pragma_macro);
+ p->name = XNEWVAR (char, nlen + 1);
+ p->name[nlen] = 0;
+ if (fread (p->name, nlen, 1, f) != 1)
+ return 0;
+ /* Save old state. */
+ m = cpp_push_definition (r, p->name);
+ if (fread (&defnlen, sizeof (defnlen), 1, f) != 1)
+ return 0;
+ defn = XNEWVAR (uchar, defnlen + 2);
+ defn[defnlen] = '\n';
+ defn[defnlen + 1] = 0;
+
+ if (fread (defn, defnlen, 1, f) != 1)
+ return 0;
+ cpp_pop_definition (r, p->name, NULL);
+ {
+ size_t namelen;
+ uchar *dn;
+
+ namelen = ustrcspn (defn, "( \n");
+ h = cpp_lookup (r, defn, namelen);
+ dn = defn + namelen;
+
+ h->type = NT_VOID;
+ h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED);
+ if (cpp_push_buffer (r, dn, ustrchr (dn, '\n') - dn, true)
+ != NULL)
+ {
+ _cpp_clean_line (r);
+ if (!_cpp_create_definition (r, h))
+ abort ();
+ _cpp_pop_buffer (r);
+ }
+ else
+ abort ();
+ }
+ p->value = cpp_push_definition (r, p->name);
+
+ free (defn);
+ p->next = r->pushed_macros;
+ r->pushed_macros = p;
+ /* Restore current state. */
+ cpp_pop_definition (r, p->name, m);
+ }
+ return 1;
+}
+
+static int
+_cpp_save_pushed_macros (cpp_reader *r, FILE *f)
+{
+ size_t count_saved = 0;
+ size_t i;
+ struct def_pragma_macro *p,**pp;
+ cpp_hashnode *node;
+ cpp_macro *m;
+ size_t defnlen;
+ const uchar *defn;
+
+ /* Get count. */
+ p = r->pushed_macros;
+ while (p != NULL)
+ {
+ count_saved++;
+ p = p->next;
+ }
+ if (fwrite (&count_saved, sizeof (count_saved), 1, f) != 1)
+ return 0;
+ if (!count_saved)
+ return 1;
+
+ pp = (struct def_pragma_macro **) alloca (sizeof (struct def_pragma_macro *)
+ * count_saved);
+ /* Store them in reverse order. */
+ p = r->pushed_macros;
+ i = count_saved;
+ while (p != NULL)
+ {
+ --i;
+ pp[i] = p;
+ p = p->next;
+ }
+ for (i = 0; i < count_saved; i++)
+ {
+ /* Save old state. */
+ m = cpp_push_definition (r, pp[i]->name);
+ /* Set temporary macro name to saved state. */
+ cpp_pop_definition (r, pp[i]->name, pp[i]->value);
+ node = _cpp_lex_identifier (r, pp[i]->name);
+ defnlen = strlen (pp[i]->name);
+ if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1
+ || fwrite (pp[i]->name, defnlen, 1, f) != 1)
+ return 0;
+ defn = cpp_macro_definition (r, node);
+ defnlen = ustrlen (defn);
+ if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1
+ || fwrite (defn, defnlen, 1, f) != 1)
+ return 0;
+ /* Restore current state. */
+ cpp_pop_definition (r, pp[i]->name, m);
+ }
+ return 1;
+}
+
/* Data structure to transform hash table nodes into a sorted list */
@@ -752,6 +885,9 @@ cpp_read_state (cpp_reader *r, const char *name, FILE *f,
if (!r->counter)
r->counter = counter;
+ /* Read pushed macros. */
+ if (! _cpp_restore_pushed_macros (r, f))
+ goto error;
return 0;
error: