@@ -324,12 +324,10 @@ cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_CORE_H) \
$(CXX_PPH_H)
cp/cp-gimplify.o: cp/cp-gimplify.c $(CXX_TREE_H) $(C_COMMON_H) \
$(TM_H) coretypes.h pointer-set.h tree-iterator.h
-
cp/name-lookup.o: cp/name-lookup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(CXX_TREE_H) $(TIMEVAR_H) gt-cp-name-lookup.h \
$(DIAGNOSTIC_CORE_H) $(FLAGS_H) debug.h tree-pretty-print.h \
$(CXX_PPH_H)
-
cp/cxx-pretty-print.o: cp/cxx-pretty-print.c $(CXX_PRETTY_PRINT_H) \
$(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h $(CXX_TREE_H) tree-pretty-print.h
cp/pph.o: cp/pph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(CPPLIB_H) \
@@ -337,4 +335,5 @@ cp/pph.o: cp/pph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(CPPLIB_H) \
fixed-value.h $(TREE_PASS_H) $(TREE_INLINE_H) tree-pretty-print.h \
$(CXX_PARSER_H) $(CXX_PPH_H) $(CXX_PPH_STREAMER_H)
cp/pph-streamer.o: cp/pph-streamer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TREE_H) $(LTO_STREAMER_H) $(CXX_PPH_STREAMER_H)
+ $(TREE_H) tree-pretty-print.h $(LTO_STREAMER_H) $(CXX_PPH_STREAMER_H) \
+ $(CXX_PPH_H) $(TREE_PASS_H) version.h cppbuiltin.h
@@ -23,68 +23,147 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "langhooks.h"
+#include "tree-pretty-print.h"
#include "lto-streamer.h"
#include "pph-streamer.h"
-
-#if !defined PPH_USE_FILE_IO
+#include "pph.h"
+#include "tree-pass.h"
+#include "version.h"
+#include "cppbuiltin.h"
+
+/* FIXME pph. This holds the FILE handle for the current PPH file
+ that we are writing. It is necessary because the LTO callbacks do
+ not allow passing a FILE handle to them. */
static FILE *current_pph_file = NULL;
-#endif
+
+
+/* Get the section with name NAME and type SECTION_TYPE from FILE_DATA.
+ Return a pointer to the start of the section contents and store
+ the length of the section in *LEN_P.
+
+ FIXME pph, this does not currently handle multiple sections. It
+ assumes that the file has exactly one section. */
+
+static const char *
+pph_get_section_data (struct lto_file_decl_data *file_data,
+ enum lto_section_type section_type ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ size_t *len)
+{
+ /* FIXME pph - Stop abusing lto_file_decl_data fields. */
+ const pph_stream *stream = (const pph_stream *) file_data->file_name;
+ *len = stream->file_size - sizeof (pph_file_header);
+ return (const char *) stream->file_data + sizeof (pph_file_header);
+}
+
+
+/* Free the section data from FILE_DATA of SECTION_TYPE and NAME that
+ starts at OFFSET and has LEN bytes. */
+
+static void
+pph_free_section_data (struct lto_file_decl_data *file_data,
+ enum lto_section_type section_type ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ const char *offset ATTRIBUTE_UNUSED,
+ size_t len ATTRIBUTE_UNUSED)
+{
+ /* FIXME pph - Stop abusing lto_file_decl_data fields. */
+ const pph_stream *stream = (const pph_stream *) file_data->file_name;
+ free (stream->file_data);
+}
+
/* Read into memory the contents of the file in STREAM. Initialize
internal tables and data structures needed to re-construct the
ASTs in the file. */
static void
-pph_file_read (pph_stream *stream)
+pph_stream_init_read (pph_stream *stream)
{
-#if defined PPH_USE_FILE_IO
- stream->file = fopen (stream->name, "rb");
-#else
- void *data;
struct stat st;
- size_t bytes_read, data_size;
-
- /* Read STREAM->NAME into the memory buffer DATA. */
- stat (stream->name, &st);
- data_size = (size_t) st.st_size;
- data = XCNEWVEC (char, data_size);
- stream->file = fopen (stream->name, "rb");
- gcc_assert (stream->file);
- bytes_read = fread (data, 1, data_size, stream->file);
- gcc_assert (bytes_read == data_size);
- fclose (stream->file);
+ size_t i, bytes_read, strtab_size, body_size;
+ int retcode;
+ pph_file_header *header;
+ const char *strtab, *body;
+
+ /* Read STREAM->NAME into the memory buffer STREAM->FILE_DATA.
+ FIXME pph, we are reading the whole file at once. This seems
+ wasteful. */
+ retcode = fstat (fileno (stream->file), &st);
+ gcc_assert (retcode == 0);
+ stream->file_size = (size_t) st.st_size;
+ stream->file_data = XCNEWVEC (char, stream->file_size);
+ bytes_read = fread (stream->file_data, 1, stream->file_size, stream->file);
+ gcc_assert (bytes_read == stream->file_size);
+
+ /* Set LTO callbacks to read the PPH file. */
+ stream->pph_sections = XCNEWVEC (struct lto_file_decl_data *,
+ PPH_NUM_SECTIONS);
+ for (i = 0; i < PPH_NUM_SECTIONS; i++)
+ {
+ stream->pph_sections[i] = XCNEW (struct lto_file_decl_data);
+ /* FIXME pph - Stop abusing fields in lto_file_decl_data. */
+ stream->pph_sections[i]->file_name = (const char *) stream;
+ }
+
+ lto_set_in_hooks (stream->pph_sections, pph_get_section_data,
+ pph_free_section_data);
+ header = (pph_file_header *) stream->file_data;
+ strtab = (const char *) header + sizeof (pph_file_header);
+ strtab_size = header->strtab_size;
+ body = strtab + strtab_size;
+ gcc_assert (stream->file_size >= strtab_size + sizeof (pph_file_header));
+ body_size = stream->file_size - strtab_size - sizeof (pph_file_header);
+
+ /* Create an input block structure pointing right after the string
+ table. */
stream->ib = XCNEW (struct lto_input_block);
- LTO_INIT_INPUT_BLOCK_PTR (stream->ib, (const char *) data, 0, data_size);
- stream->data_in = lto_data_in_create (NULL, NULL, 0, NULL);
-#endif
+ LTO_INIT_INPUT_BLOCK_PTR (stream->ib, body, 0, body_size);
+ stream->data_in = lto_data_in_create (stream->pph_sections[0], strtab,
+ strtab_size, NULL);
+}
+
+
+/* Initialize buffers and tables in STREAM for writing. */
+
+static void
+pph_stream_init_write (pph_stream *stream)
+{
+ stream->out_state = lto_new_out_decl_state ();
+ lto_push_out_decl_state (stream->out_state);
+ stream->decl_state_stream = XCNEW (struct lto_output_stream);
+ stream->ob = create_output_block (LTO_section_decls);
}
-/* Create a new PPH stream to be stored on the file called NAME. If
- TO_READ_P is true, the file is open for reading. */
+/* Create a new PPH stream to be stored on the file called NAME.
+ MODE is passed to fopen directly. */
pph_stream *
-pph_stream_open (const char *name, bool to_read_p)
+pph_stream_open (const char *name, const char *mode)
{
- pph_stream *stream = XCNEW (pph_stream);
- stream->name = xstrdup (name);
- if (!to_read_p)
+ pph_stream *stream;
+ FILE *f;
+
+ stream = NULL;
+ f = fopen (name, mode);
+ if (f)
{
- stream->file = fopen (name, "wb");
- stream->out_state = lto_new_out_decl_state ();
- lto_push_out_decl_state (stream->out_state);
- stream->decl_state_stream = XCNEW (struct lto_output_stream);
- stream->ob = create_output_block (LTO_section_decls);
+ stream = XCNEW (pph_stream);
+ stream->file = f;
+ stream->name = xstrdup (name);
+ stream->write_p = (strchr (mode, 'w') != NULL);
+ if (stream->write_p)
+ pph_stream_init_write (stream);
+ else
+ pph_stream_init_read (stream);
}
- else
- pph_file_read (stream);
return stream;
}
-#if !defined PPH_USE_FILE_IO
/* Callback for lang_hooks.lto.begin_section. Open file NAME. */
static void
@@ -112,31 +191,44 @@ static void
pph_stream_end_section (void)
{
}
-#endif
-/* Close PPH stream STREAM. Write all the ASTs to disk and deallocate
- all memory used by it. */
+/* Write the header for the PPH file represented by STREAM. */
-void
-pph_stream_close (pph_stream *stream)
+static void
+pph_stream_write_header (pph_stream *stream)
{
-#if defined PPH_USE_FILE_IO
- fclose (stream->file);
-#else
- gcc_assert (current_pph_file == NULL);
- current_pph_file = stream->file;
+ pph_file_header header;
+ struct lto_output_stream header_stream;
+ int major, minor, patchlevel;
+
+ /* Collect version information. */
+ parse_basever (&major, &minor, &patchlevel);
+ gcc_assert (major == (char) major);
+ gcc_assert (minor == (char) minor);
+ gcc_assert (patchlevel == (char) patchlevel);
+
+ /* Write the header for the PPH file. */
+ memset (&header, 0, sizeof (header));
+ strcpy (header.id_str, pph_id_str);
+ header.major_version = (char) major;
+ header.minor_version = (char) minor;
+ header.patchlevel = (char) patchlevel;
+ header.strtab_size = stream->ob->string_stream->total_size;
+
+ memset (&header_stream, 0, sizeof (header_stream));
+ lto_output_data_stream (&header_stream, &header, sizeof (header));
+ lto_write_stream (&header_stream);
+}
- /* Redirect the LTO basic I/O langhooks. */
- lang_hooks.lto.begin_section = pph_stream_begin_section;
- lang_hooks.lto.append_data = pph_stream_write;
- lang_hooks.lto.end_section = pph_stream_end_section;
- /* Write the state buffers built by pph_stream_output() calls. */
- lto_begin_section (stream->name, false);
+/* Write the body of the PPH file represented by STREAM. */
- /* Make string 0 be a NULL string. */
- lto_output_1_stream (stream->ob->string_stream, 0);
+static void
+pph_stream_write_body (pph_stream *stream)
+{
+ /* Write the string table. */
+ lto_write_stream (stream->ob->string_stream);
/* Write out the physical representation for every AST in all the
streams in STREAM->OUT_STATE. */
@@ -148,10 +240,148 @@ pph_stream_close (pph_stream *stream)
/* Finally, physically write all the streams. */
lto_write_stream (stream->ob->main_stream);
- lto_write_stream (stream->ob->string_stream);
+}
+
+
+/* Close PPH stream STREAM. Write all the ASTs to disk and deallocate
+ all memory used by it. */
+
+void
+pph_stream_close (pph_stream *stream)
+{
+ if (stream->write_p)
+ {
+ gcc_assert (current_pph_file == NULL);
+ current_pph_file = stream->file;
+
+ /* Redirect the LTO basic I/O langhooks. */
+ lang_hooks.lto.begin_section = pph_stream_begin_section;
+ lang_hooks.lto.append_data = pph_stream_write;
+ lang_hooks.lto.end_section = pph_stream_end_section;
+
+ /* Write the state buffers built by pph_output_*() calls. */
+ lto_begin_section (stream->name, false);
+ pph_stream_write_header (stream);
+ pph_stream_write_body (stream);
+ lto_end_section ();
+ }
- lto_end_section ();
fclose (stream->file);
- current_pph_file = NULL;
-#endif
+ stream->file = current_pph_file = NULL;
+}
+
+
+/* Data types supported by the PPH tracer. */
+enum pph_trace_type
+{
+ PPH_TRACE_TREE,
+ PPH_TRACE_UINT,
+ PPH_TRACE_BYTES,
+ PPH_TRACE_STRING
+};
+
+/* Print tracing information for STREAM on pph_logfile. DATA is the
+ memory area to display, SIZE is the number of bytes to print, TYPE
+ is the kind of data to print. */
+
+static void
+pph_stream_trace (pph_stream *stream, const void *data, unsigned int nbytes,
+ enum pph_trace_type type)
+{
+ const char *op = (stream->write_p) ? "write" : "read";
+ const char *type_s[] = { "tree", "uint", "bytes", "string" };
+
+ fprintf (pph_logfile, "*** %s: op=%s, type=%s, size=%u, value=",
+ stream->name, op, type_s[type], (unsigned) nbytes);
+
+ switch (type)
+ {
+ case PPH_TRACE_TREE:
+ {
+ const_tree t = (const_tree) data;
+ print_generic_expr (pph_logfile, CONST_CAST (union tree_node *, t),
+ TDF_SLIM);
+ }
+ break;
+
+ case PPH_TRACE_UINT:
+ {
+ unsigned int val = *((const unsigned int *) data);
+ fprintf (pph_logfile, "%u (0x%x)", val, val);
+ }
+ break;
+
+ case PPH_TRACE_BYTES:
+ {
+ size_t i;
+ const char *buffer = (const char *) data;
+ for (i = 0; i < MIN (nbytes, 100); i++)
+ {
+ if (ISPRINT (buffer[i]))
+ fprintf (pph_logfile, "%c", buffer[i]);
+ else
+ fprintf (pph_logfile, "[0x%02x]", (unsigned int) buffer[i]);
+ }
+ }
+ break;
+
+ case PPH_TRACE_STRING:
+ if (data)
+ fprintf (pph_logfile, "%.*s", (int) nbytes, (const char *) data);
+ else
+ fprintf (pph_logfile, "<nil>");
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ fputc ('\n', pph_logfile);
+}
+
+
+/* Show tracing information for T on STREAM. */
+
+void
+pph_stream_trace_tree (pph_stream *stream, tree t)
+{
+ pph_stream_trace (stream, t, tree_code_size (TREE_CODE (t)), PPH_TRACE_TREE);
+}
+
+
+/* Show tracing information for VAL on STREAM. */
+
+void
+pph_stream_trace_uint (pph_stream *stream, unsigned int val)
+{
+ pph_stream_trace (stream, &val, sizeof (val), PPH_TRACE_UINT);
+}
+
+
+/* Show tracing information for NBYTES bytes of memory area DATA on
+ STREAM. */
+
+void
+pph_stream_trace_bytes (pph_stream *stream, const void *data, size_t nbytes)
+{
+ pph_stream_trace (stream, data, nbytes, PPH_TRACE_BYTES);
+}
+
+
+/* Show tracing information for S on STREAM. */
+
+void
+pph_stream_trace_string (pph_stream *stream, const char *s)
+{
+ pph_stream_trace (stream, s, s ? strlen (s) : 0, PPH_TRACE_STRING);
+}
+
+
+/* Show tracing information for LEN bytes of S on STREAM. */
+
+void
+pph_stream_trace_string_with_length (pph_stream *stream, const char *s,
+ unsigned int len)
+{
+ pph_stream_trace (stream, s, len, PPH_TRACE_STRING);
}
@@ -24,9 +24,32 @@ along with GCC; see the file COPYING3. If not see
#include "lto-streamer.h"
#include "tree.h"
-/* FIXME pph - Workaround incomplete PPH streamer. Use regular FILE I/O. */
-#define PPH_USE_FILE_IO 1
+/* Number of sections in a PPH file. FIXME, currently only one section
+ is supported. To add more, it will also be necessary to handle
+ section names in pph_get_section_data and pph_free_section_data. */
+#define PPH_NUM_SECTIONS 1
+/* String to identify PPH files. Keep it to 7 characters, so it takes
+ exactly 8 bytes in the file. */
+static const char pph_id_str[] = "PPH0x42";
+
+/* Structure of the header of a PPH file. */
+typedef struct pph_file_header {
+ /* Identification string. */
+ char id_str[sizeof(pph_id_str)];
+
+ /* Version information. */
+ char major_version;
+ char minor_version;
+ char patchlevel;
+
+ /* Size of the string table in bytes. */
+ unsigned int strtab_size;
+} pph_file_header;
+
+
+/* A PPH stream contains all the data and attributes needed to
+ write symbols, declarations and other parsing products to disk. */
typedef struct pph_stream {
/* Path name of the PPH file. */
const char *name;
@@ -45,16 +68,29 @@ typedef struct pph_stream {
struct lto_input_block *ib;
/* String tables and other descriptors used by the LTO reading
- routines. */
+ routines. NULL when the file is opened for reading. */
struct data_in *data_in;
- /* Nonzero if the stream was open for writing. */
+ /* Array of sections in the PPH file. */
+ struct lto_file_decl_data **pph_sections;
+
+ /* Buffer holding the file contents. FIXME pph, we are bringing
+ the whole file in memory at once. This seems wasteful. */
+ char *file_data;
+ size_t file_size;
+
+ /* Nonzero if the stream was opened for writing. */
unsigned int write_p : 1;
} pph_stream;
/* In pph-streamer.c. */
-pph_stream *pph_stream_open (const char *, bool);
+pph_stream *pph_stream_open (const char *, const char *);
void pph_stream_close (pph_stream *);
+void pph_stream_trace_tree (pph_stream *, tree);
+void pph_stream_trace_uint (pph_stream *, unsigned int);
+void pph_stream_trace_bytes (pph_stream *, const void *, size_t);
+void pph_stream_trace_string (pph_stream *, const char *);
+void pph_stream_trace_string_with_length (pph_stream *, const char *, unsigned);
/* Inline functions. */
@@ -63,52 +99,36 @@ void pph_stream_close (pph_stream *);
static inline void
pph_output_tree (pph_stream *stream ATTRIBUTE_UNUSED, tree t ATTRIBUTE_UNUSED)
{
-#if defined PPH_USE_FILE_IO
- gcc_unreachable ();
-#else
+ if (flag_pph_tracer)
+ pph_stream_trace_tree (stream, t);
lto_output_tree (stream->ob, t, true);
-#endif
}
/* Write a uint VALUE to STREAM. */
static inline void
pph_output_uint (pph_stream *stream, unsigned int value)
{
-#if defined PPH_USE_FILE_IO
- fwrite (&value, 1, sizeof (value), stream->file);
-#else
+ if (flag_pph_tracer)
+ pph_stream_trace_uint (stream, value);
lto_output_sleb128_stream (stream->ob->main_stream, value);
-#endif
}
/* Write N bytes from P to STREAM. */
static inline void
pph_output_bytes (pph_stream *stream, const void *p, size_t n)
{
-#if defined PPH_USE_FILE_IO
- fwrite (p, 1, n, stream->file);
-#else
+ if (flag_pph_tracer)
+ pph_stream_trace_bytes (stream, p, n);
lto_output_data_stream (stream->ob->main_stream, p, n);
-#endif
}
/* Write string STR to STREAM. */
static inline void
pph_output_string (pph_stream *stream, const char *str)
{
-#if defined PPH_USE_FILE_IO
- if (str == NULL)
- pph_output_uint (stream, -1U);
- else
- {
- unsigned length = strlen (str);
- pph_output_uint (stream, length);
- if (length > 0)
- pph_output_bytes (stream, str, length);
- }
-#else
lto_output_string (stream->ob, stream->ob->main_stream, str);
-#endif
+ if (flag_pph_tracer)
+ pph_stream_trace_string (stream, str);
}
/* Write string STR of length LEN to STREAM. */
@@ -116,35 +136,29 @@ static inline void
pph_output_string_with_length (pph_stream *stream, const char *str,
unsigned int len)
{
-#if defined PPH_USE_FILE_IO
- if (str == NULL)
- pph_output_uint (stream, -1U);
+ if (str)
+ lto_output_string_with_length (stream->ob, stream->ob->main_stream,
+ str, len + 1);
else
{
- pph_output_uint (stream, len);
- if (len > 0)
- pph_output_bytes (stream, str, len);
+ /* lto_output_string_with_length does not handle NULL strings,
+ but lto_output_string does. */
+ pph_output_string (stream, NULL);
}
-#else
- lto_output_string_with_length (stream->ob, stream->ob->main_stream, str, len);
-#endif
+
+ if (flag_pph_tracer)
+ pph_stream_trace_string_with_length (stream, str, len);
}
/* Read an unsigned HOST_WIDE_INT integer from STREAM. */
-static inline unsigned
+static inline unsigned int
pph_input_uint (pph_stream *stream)
{
-#if defined PPH_USE_FILE_IO
- unsigned num;
- size_t received;
- received = fread (&num, sizeof num, 1, stream->file);
- gcc_assert (received == 1);
- return num;
-#else
HOST_WIDE_INT unsigned n = lto_input_uleb128 (stream->ib);
gcc_assert (n == (unsigned) n);
+ if (flag_pph_tracer)
+ pph_stream_trace_uint (stream, n);
return (unsigned) n;
-#endif
}
/* Read N bytes from STREAM into P. The caller is responsible for
@@ -152,12 +166,9 @@ pph_input_uint (pph_stream *stream)
static inline void
pph_input_bytes (pph_stream *stream, void *p, size_t n)
{
-#if defined PPH_USE_FILE_IO
- size_t received = fread (p, 1, n, stream->file);
- gcc_assert (received == n);
-#else
lto_input_data_block (stream->ib, p, n);
-#endif
+ if (flag_pph_tracer)
+ pph_stream_trace_bytes (stream, p, n);
}
/* Read and return a string of up to MAX characters from STREAM.
@@ -167,20 +178,10 @@ pph_input_bytes (pph_stream *stream, void *p, size_t n)
static inline const char *
pph_input_string (pph_stream *stream)
{
-#if defined PPH_USE_FILE_IO
- char *buf = NULL;
- unsigned len;
- size_t received = fread (&len, sizeof len, 1, stream->file);
- gcc_assert (received == 1);
- if (len > 0 && len != -1U)
- {
- buf = XCNEWVEC (char, len + 1);
- received = fread (buf, 1, len, stream->file);
- }
- return (const char *) buf;
-#else
- return lto_input_string (stream->data_in, stream->ib);
-#endif
+ const char *s = lto_input_string (stream->data_in, stream->ib);
+ if (flag_pph_tracer)
+ pph_stream_trace_string (stream, s);
+ return s;
}
/* Load an AST from STREAM. Return the corresponding tree. */
@@ -188,11 +189,10 @@ pph_input_string (pph_stream *stream)
static inline tree
pph_input_tree (pph_stream *stream ATTRIBUTE_UNUSED)
{
-#if defined PPH_USE_FILE_IO
- gcc_unreachable ();
-#else
- return lto_input_tree (stream->ib, stream->data_in);
-#endif
+ tree t = lto_input_tree (stream->ib, stream->data_in);
+ if (flag_pph_tracer)
+ pph_stream_trace_tree (stream, t);
+ return t;
}
#endif /* GCC_CP_PPH_STREAMER_H */
@@ -197,18 +197,17 @@ pth_name_for (const char *name)
}
-/* Open an image file for path NAME. READ_P is true if the file should
- be opened for reading. */
+/* Open an image file for path NAME. MODE is as in fopen. */
static pph_stream *
-pth_file_for (const char *name, bool read_p)
+pth_file_for (const char *name, const char *mode)
{
char *s;
pph_stream *f;
s = pth_name_for (name);
- f = pph_stream_open (s, read_p);
- if (f->file == NULL)
+ f = pph_stream_open (s, mode);
+ if (!f)
fatal_error ("can%'t open token stream file %s: %m", s);
free (s);
@@ -462,9 +461,16 @@ pph_print_macro_defs_before (pph_stream *stream, cpp_idents_used *identifiers)
const char *before = entry->before_str;
if (before)
- fprintf (stream->file, "#define %s%s\n", ident, before);
+ {
+ pph_output_string (stream, "#define ");
+ pph_output_string (stream, ident);
+ pph_output_string (stream, before);
+ }
else
- fprintf (stream->file, "#undef %s\n", ident);
+ {
+ pph_output_string (stream, "#undef ");
+ pph_output_string (stream, ident);
+ }
}
}
@@ -487,9 +493,16 @@ pph_print_macro_defs_after (pph_stream *stream, cpp_idents_used *identifiers)
if (before != after)
{
if (after && (!before || strcmp (after, before) != 0))
- fprintf (stream->file, "#define %s%s\n", ident, after);
+ {
+ pph_output_string (stream, "#define ");
+ pph_output_string (stream, ident);
+ pph_output_string (stream, after);
+ }
else if (before)
- fprintf (stream->file, "#undef %s\n", ident);
+ {
+ pph_output_string (stream, "#undef ");
+ pph_output_string (stream, ident);
+ }
}
}
}
@@ -864,7 +877,7 @@ pth_save_image (pth_image *image)
/* Open the stream in append mode since we have already created
it in pth_new_image. */
- stream = pth_file_for (image->fname, false);
+ stream = pth_file_for (image->fname, "wb");
/* Write a header to recognize the file later. */
pth_write_header (image, stream);
@@ -984,7 +997,6 @@ pth_load_token_value (cp_token *token, pph_stream *f)
case CPP_NAME:
str = pph_input_string (f);
token->u.value = get_identifier (str);
- free (CONST_CAST (char *, str));
break;
case CPP_KEYWORD:
@@ -1005,7 +1017,6 @@ pth_load_token_value (cp_token *token, pph_stream *f)
case CPP_STRING32:
str = pph_input_string (f);
token->u.value = build_string (strlen (str), str);
- free (CONST_CAST (char *, str));
break;
case CPP_PRAGMA:
@@ -1051,7 +1062,6 @@ pth_load_identifiers (cpp_idents_used *identifiers, pph_stream *stream)
identifiers->entries[j].ident_len = ident_len;
identifiers->entries[j].ident_str =
(const char *) obstack_copy0 (identifiers->strings, s, ident_len);
- free (CONST_CAST (char *, s));
s = pph_input_string (stream);
if (s)
@@ -1060,7 +1070,6 @@ pth_load_identifiers (cpp_idents_used *identifiers, pph_stream *stream)
identifiers->entries[j].before_len = before_len;
identifiers->entries[j].before_str = (const char *)
obstack_copy0 (identifiers->strings, s, before_len);
- free (CONST_CAST (char *, s));
}
else
{
@@ -1077,7 +1086,6 @@ pth_load_identifiers (cpp_idents_used *identifiers, pph_stream *stream)
identifiers->entries[j].after_len = after_len;
identifiers->entries[j].after_str = (const char *)
obstack_copy0 (identifiers->strings, s, after_len);
- free (CONST_CAST (char *, s));
}
else
{
@@ -1162,7 +1170,6 @@ pth_load_include (pth_state *state, pth_image *image, cpp_reader *reader,
s = pph_input_string (stream);
include->image = pth_image_lookup (state, s, reader);
- free (CONST_CAST (char *, s));
tmp = pph_input_uint (stream);
include->itype = (enum include_type) tmp;
@@ -1184,14 +1191,17 @@ pth_load_image (pth_state *state, pth_image *image, cpp_reader *reader)
{
pph_stream *stream;
unsigned i, num;
+ char *buf;
timevar_push (TV_PTH_LOAD);
- stream = pth_file_for (image->fname, true);
+ stream = pth_file_for (image->fname, "rb");
/* Skip over the header, as we assume that it has already been
validated by pth_have_valid_image_for. */
- fseek (stream->file, (long) pth_header_len (), SEEK_SET);
+ buf = XCNEWVEC (char, pth_header_len ());
+ pph_input_bytes (stream, buf, pth_header_len ());
+ free (buf);
/* Read the include-hunk (IH) sequencing vector. */
num = pph_input_uint (stream);
@@ -1258,7 +1268,8 @@ pth_have_valid_image_for (const char *fname, pth_image *image)
goto invalid_img;
/* If the file exists, check if it has a valid signature. */
- f = pph_stream_open (img_name, true);
+ f = pph_stream_open (img_name, "rb");
+ gcc_assert (f);
good_id = pth_id_str ();
id = XCNEWVEC (char, strlen (good_id) + 1);
@@ -1834,17 +1845,17 @@ pth_file_change (cpp_reader *reader, const struct line_map *map)
typedef void (*write_pph_format)(pph_stream *stream, tree decl, int flags);
+/* Forward declarations to break cyclic references. */
static void
-write_pph_namespace (pph_stream *stream, tree decl, write_pph_format fmt, int flags);
+write_pph_namespace (pph_stream *, tree, write_pph_format, int);
/* Write symbol to PPH output file like C. */
static void
-write_pph_print (pph_stream *stream, tree decl, int flags)
+write_pph_print (pph_stream *stream, tree decl, int flags ATTRIBUTE_UNUSED)
{
- print_generic_decl (stream->file, decl, flags | TDF_VISDEF);
- fprintf (stream->file, "\n");
+ pph_output_tree (stream, decl);
}
@@ -1860,7 +1871,8 @@ write_pph_dump (pph_stream *stream, tree decl, int flags)
/* Write symbol to PPH output file. */
static void
-write_pph_symbol (pph_stream *stream, tree decl, write_pph_format fmt, int flags)
+write_pph_symbol (pph_stream *stream, tree decl, write_pph_format fmt,
+ int flags)
{
if (TREE_CODE (decl) == NAMESPACE_DECL)
write_pph_namespace (stream, decl, fmt, flags);
@@ -1884,7 +1896,8 @@ write_pph_namespace_1 (declvisitor vtor, pph_stream *stream, tree decl,
}
static void
-write_pph_namespace (pph_stream *stream, tree decl, write_pph_format fmt, int flags)
+write_pph_namespace (pph_stream *stream, tree decl, write_pph_format fmt,
+ int flags)
{
struct cp_binding_level *level = NAMESPACE_LEVEL (decl);
decl = level->namespaces;
@@ -1903,8 +1916,6 @@ write_pph_file_object (pph_stream *stream, cpp_idents_used *idents_used)
{
int flags = 0;
pth_save_identifiers (idents_used, stream);
- fprintf (stream->file, "\n====\n");
- /* FIX pph: Wrong format for writing decls. */
write_pph_namespace (stream, global_namespace, write_pph_print, flags);
}
@@ -1943,7 +1954,7 @@ write_pph_file (void)
if (flag_pph_debug >= 1)
fprintf (pph_logfile, "PPH: Writing %s\n", pph_out_file);
- stream = pph_stream_open (pph_out_file, false);
+ stream = pph_stream_open (pph_out_file, "wb");
if (!stream)
fatal_error ("Cannot open PPH file for writing: %s: %m", pph_out_file);
@@ -2040,8 +2051,8 @@ read_pph_file (const char *filename)
if (flag_pph_debug >= 1)
fprintf (pph_logfile, "PPH: Reading %s\n", filename);
- stream = pph_stream_open (filename, true);
- if (!stream->file)
+ stream = pph_stream_open (filename, "rb");
+ if (!stream)
fatal_error ("Cannot open PPH file for reading: %s: %m", filename);
if (flag_pph_fmt == 0)
@@ -2083,7 +2094,7 @@ pth_include_handler (cpp_reader *reader ATTRIBUTE_UNUSED,
/* Record a #include or #include_next for PPH. */
static void
-pph_include_handler (cpp_reader *reader /*FIXME pph: ATTRIBUTE_UNUSED */,
+pph_include_handler (cpp_reader *reader,
location_t loc ATTRIBUTE_UNUSED,
const unsigned char *dname,
const char *name,
@@ -2101,7 +2112,7 @@ pph_include_handler (cpp_reader *reader /*FIXME pph: ATTRIBUTE_UNUSED */,
}
pph_file = query_pph_include_map (name);
- if (pph_file != NULL && ! cpp_included_before (reader, name, input_location))
+ if (pph_file != NULL && !cpp_included_before (reader, name, input_location))
read_pph_file (pph_file);
}