Main streaming support. See http://gcc.gnu.org/ml/gcc-patches/2011-03/msg01556.html for details.
cp/ChangeLog.pph 2011-03-23 Diego Novillo <dnovi...@google.com> * Make-lang.in (cp/pph-streamer.o): Add dependencies on tree-pretty-print.h, CXX_PPH_H, TREE_PASS_H, version.h and cppbuiltin.h * pph-streamer.c: Include tree-pretty-print.h, pph.h, tree-pass.h, version.h and cppbuiltin.h. (pph_get_section_data): New. (pph_free_section_data): New. (pph_stream_init_read): Rename from pph_file_read. Initialize LTO streaming data structures. Read pph file in memory. (pph_stream_init_write): Factor out of ... (pph_stream_open): ... here. (pph_stream_write_header): New. (pph_stream_write_body): Factor out of ... (pph_stream_close): ... here. Call pph_stream_write_header. (enum pph_trace_type): Declare. (pph_stream_trace): New. (pph_stream_trace_tree): New. (pph_stream_trace_uint): New. (pph_stream_trace_bytes): New. (pph_stream_trace_string): New. (pph_stream_trace_string_with_length): New. * pph-streamer.h (PPH_NUM_SECTIONS): Define. (PPH_USE_FILE_IO): Remove. Update all users. (pph_id_str): Define. (pph_file_header): Declare. (pph_stream): Add fields pph_sections, file_data and file_size. (pph_stream_open): Change second argument to const char *. Update all users. (pph_stream_trace_tree): Declare. (pph_stream_trace_uint): Declare. (pph_stream_trace_bytes): Declare. (pph_stream_trace_string): Declare. (pph_stream_trace_string_with_length): Declare. (pph_output_tree): Call pph_stream_trace_tree if flag_pph_tracer is enabled. (pph_input_tree): Likewise. (pph_output_uint): Call pph_stream_trace_uint if flag_pph_tracer is enabled. (pph_input_uint): Likewise. (pph_output_bytes): Call pph_stream_trace_bytes if flag_pph_tracer is enabled. (pph_input_bytes): Likewise. (pph_output_string): Call pph_stream_trace_string if flag_pph_tracer is enabled. (pph_input_string): Likewise. (pph_output_string_with_length): Call pph_stream_trace_string_with_length if flag_pph_tracer is enabled. * pph.c (pph_print_macro_defs_before): Call pph_output_string. (pph_print_macro_defs_after): Likewise. (pth_load_token_value): Do not free the read string. (pth_load_identifiers): Likewise. (pth_load_include): Likewise. (pth_load_image): Call pph_input_bytes to read the header. (write_pph_print): Call pph_output_tree. (write_pph_file_object): Remove fprintf() call. (pth_include_handler): Remove FIXME marker. (pph_include_handler): Tidy. diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 3a52e1f..bcb2ba1 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -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 diff --git a/gcc/cp/pph-streamer.c b/gcc/cp/pph-streamer.c index c170f1f..cca42e6 100644 --- a/gcc/cp/pph-streamer.c +++ b/gcc/cp/pph-streamer.c @@ -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); } diff --git a/gcc/cp/pph-streamer.h b/gcc/cp/pph-streamer.h index 1b04d65..afffe35 100644 --- a/gcc/cp/pph-streamer.h +++ b/gcc/cp/pph-streamer.h @@ -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 */ diff --git a/gcc/cp/pph.c b/gcc/cp/pph.c index e0ddf24..5ec7916 100644 --- a/gcc/cp/pph.c +++ b/gcc/cp/pph.c @@ -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); } -- This patch is available for review at http://codereview.appspot.com/4303049