Commit c0d578e6 by Geoffrey Keating Committed by Geoffrey Keating

c-opts.c (c_common_handle_option): Handle -fpch-preprocess.

2004-06-21  Geoffrey Keating  <geoffk@apple.com>

	* c-opts.c (c_common_handle_option): Handle -fpch-preprocess.
	* c-common.h (flag_pch_preprocess): Declare.
	(c_common_pch_pragma): Likewise.
	* c-common.c (flag_pch_preprocess): New.
	* c-pch.c (c_common_read_pch): Support -fpreprocess-only.
	(c_common_pch_pragma): New.
	* c-ppoutput.c (cb_read_pch): New.
	(init_pp_output): Support -fpch-preprocess.
	* c-pragma.c (init_pragma): Support #pragma GNUC pch_preprocess.
	* c.opt (fpch-preprocess): New.
	* gcc.c (cpp_options): When save-temps, pass -fpch-preprocess.
	* doc/cppopts.texi: Document -fpch-preprocess.
	* doc/invoke.texi (Precompiled Headers): Mention that
	-fpreprocessed is safe for PCH.  Mention that if an option is
	listed as safe that doesn't mean it does what you expect.

Index: gcc/testsuite/ChangeLog
2004-06-21  Geoffrey Keating  <geoffk@apple.com>

	* gcc.dg/pch/save-temps-1.c: New file.
	* gcc.dg/pch/save-temps-1.hs: New file.

Index: libcpp/ChangeLog
2004-06-21  Geoffrey Keating  <geoffk@apple.com>

	* files.c (should_stack_file): Correct swapped parameters to call
	to cb.read_pch.
	* pch.c (cpp_valid_state): Handle -fpreprocessed.

From-SVN: r83478
parent f6144c34
2004-06-21 Geoffrey Keating <geoffk@apple.com>
* c-opts.c (c_common_handle_option): Handle -fpch-preprocess.
* c-common.h (flag_pch_preprocess): Declare.
(c_common_pch_pragma): Likewise.
* c-common.c (flag_pch_preprocess): New.
* c-pch.c (c_common_read_pch): Support -fpreprocess-only.
(c_common_pch_pragma): New.
* c-ppoutput.c (cb_read_pch): New.
(init_pp_output): Support -fpch-preprocess.
* c-pragma.c (init_pragma): Support #pragma GNUC pch_preprocess.
* c.opt (fpch-preprocess): New.
* gcc.c (cpp_options): When save-temps, pass -fpch-preprocess.
* doc/cppopts.texi: Document -fpch-preprocess.
* doc/invoke.texi (Precompiled Headers): Mention that
-fpreprocessed is safe for PCH. Mention that if an option is
listed as safe that doesn't mean it does what you expect.
2004-06-22 Ben Elliston <bje@au.ibm.com> 2004-06-22 Ben Elliston <bje@au.ibm.com>
* tree-ssa.c (ssa_redirect_edge): Correct leading comment. * tree-ssa.c (ssa_redirect_edge): Correct leading comment.
......
...@@ -217,6 +217,10 @@ char flag_dump_macros; ...@@ -217,6 +217,10 @@ char flag_dump_macros;
char flag_dump_includes; char flag_dump_includes;
/* Nonzero means process PCH files while preprocessing. */
bool flag_pch_preprocess;
/* The file name to which we should write a precompiled header, or /* The file name to which we should write a precompiled header, or
NULL if no header will be written in this compile. */ NULL if no header will be written in this compile. */
......
...@@ -350,6 +350,10 @@ extern char flag_dump_macros; ...@@ -350,6 +350,10 @@ extern char flag_dump_macros;
extern char flag_dump_includes; extern char flag_dump_includes;
/* Nonzero means process PCH files while preprocessing. */
extern bool flag_pch_preprocess;
/* The file name to which we should write a precompiled header, or /* The file name to which we should write a precompiled header, or
NULL if no header will be written in this compile. */ NULL if no header will be written in this compile. */
...@@ -1096,12 +1100,15 @@ extern void c_genericize (tree); ...@@ -1096,12 +1100,15 @@ extern void c_genericize (tree);
extern int c_gimplify_expr (tree *, tree *, tree *); extern int c_gimplify_expr (tree *, tree *, tree *);
extern tree c_build_bind_expr (tree, tree); extern tree c_build_bind_expr (tree, tree);
/* In c-pch.c */
extern void pch_init (void); extern void pch_init (void);
extern int c_common_valid_pch (cpp_reader *pfile, const char *name, int fd); extern int c_common_valid_pch (cpp_reader *pfile, const char *name, int fd);
extern void c_common_read_pch (cpp_reader *pfile, const char *name, int fd, extern void c_common_read_pch (cpp_reader *pfile, const char *name, int fd,
const char *orig); const char *orig);
extern void c_common_write_pch (void); extern void c_common_write_pch (void);
extern void c_common_no_more_pch (void); extern void c_common_no_more_pch (void);
extern void c_common_pch_pragma (cpp_reader *pfile);
extern void builtin_define_with_value (const char *, const char *, int); extern void builtin_define_with_value (const char *, const char *, int);
extern void c_stddef_cpp_builtins (void); extern void c_stddef_cpp_builtins (void);
extern void fe_file_change (const struct line_map *); extern void fe_file_change (const struct line_map *);
......
...@@ -879,6 +879,10 @@ c_common_handle_option (size_t scode, const char *arg, int value) ...@@ -879,6 +879,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
cpp_opts->restore_pch_deps = value; cpp_opts->restore_pch_deps = value;
break; break;
case OPT_fpch_preprocess:
flag_pch_preprocess = value;
break;
case OPT_fpermissive: case OPT_fpermissive:
flag_permissive = value; flag_permissive = value;
break; break;
......
...@@ -393,8 +393,6 @@ c_common_read_pch (cpp_reader *pfile, const char *name, ...@@ -393,8 +393,6 @@ c_common_read_pch (cpp_reader *pfile, const char *name,
{ {
FILE *f; FILE *f;
struct c_pch_header h; struct c_pch_header h;
char *buf;
unsigned long written;
struct save_macro_data *smd; struct save_macro_data *smd;
f = fdopen (fd, "rb"); f = fdopen (fd, "rb");
...@@ -412,18 +410,30 @@ c_common_read_pch (cpp_reader *pfile, const char *name, ...@@ -412,18 +410,30 @@ c_common_read_pch (cpp_reader *pfile, const char *name,
return; return;
} }
buf = xmalloc (16384); if (!flag_preprocess_only)
for (written = 0; written < h.asm_size; )
{ {
long size = h.asm_size - written; unsigned long written;
if (size > 16384) char * buf = xmalloc (16384);
size = 16384;
if (fread (buf, size, 1, f) != 1 for (written = 0; written < h.asm_size; )
|| fwrite (buf, size, 1, asm_out_file) != 1) {
cpp_errno (pfile, CPP_DL_ERROR, "reading"); long size = h.asm_size - written;
written += size; if (size > 16384)
size = 16384;
if (fread (buf, size, 1, f) != 1
|| fwrite (buf, size, 1, asm_out_file) != 1)
cpp_errno (pfile, CPP_DL_ERROR, "reading");
written += size;
}
free (buf);
}
else
{
/* If we're preprocessing, don't write to a NULL
asm_out_file. */
if (fseek (f, h.asm_size, SEEK_CUR) != 0)
cpp_errno (pfile, CPP_DL_ERROR, "seeking");
} }
free (buf);
cpp_prepare_state (pfile, &smd); cpp_prepare_state (pfile, &smd);
...@@ -446,3 +456,47 @@ c_common_no_more_pch (void) ...@@ -446,3 +456,47 @@ c_common_no_more_pch (void)
host_hooks.gt_pch_use_address (NULL, 0, -1, 0); host_hooks.gt_pch_use_address (NULL, 0, -1, 0);
} }
} }
/* Handle #pragma GCC pch_preprocess, to load in the PCH file. */
#ifndef O_BINARY
# define O_BINARY 0
#endif
void
c_common_pch_pragma (cpp_reader *pfile)
{
tree name_t;
const char *name;
int fd;
if (c_lex (&name_t) != CPP_STRING)
{
error ("malformed #pragma GCC pch_preprocess, ignored");
return;
}
if (! cpp_get_options (pfile)->preprocessed)
{
error ("pch_preprocess pragma should only be used with -fpreprocessed");
inform ("use #include instead");
return;
}
name = TREE_STRING_POINTER (name_t);
fd = open (name, O_RDONLY | O_BINARY, 0666);
if (fd == -1)
fatal_error ("%s: couldn't open PCH file: %m\n", name);
if (c_common_valid_pch (pfile, name, fd) != 1)
{
if (!cpp_get_options (pfile)->warn_invalid_pch)
inform ("use -Winvalid-pch for more information");
fatal_error ("%s: PCH file was invalid", name);
}
c_common_read_pch (pfile, name, fd, name);
close (fd);
}
...@@ -57,6 +57,8 @@ static void cb_include (cpp_reader *, fileline, const unsigned char *, ...@@ -57,6 +57,8 @@ static void cb_include (cpp_reader *, fileline, const unsigned char *,
const char *, int); const char *, int);
static void cb_ident (cpp_reader *, fileline, const cpp_string *); static void cb_ident (cpp_reader *, fileline, const cpp_string *);
static void cb_def_pragma (cpp_reader *, fileline); static void cb_def_pragma (cpp_reader *, fileline);
static void cb_read_pch (cpp_reader *pfile, const char *name,
int fd, const char *orig_name);
/* Preprocess and output. */ /* Preprocess and output. */
void void
...@@ -106,6 +108,12 @@ init_pp_output (FILE *out_stream) ...@@ -106,6 +108,12 @@ init_pp_output (FILE *out_stream)
if (flag_dump_includes) if (flag_dump_includes)
cb->include = cb_include; cb->include = cb_include;
if (flag_pch_preprocess)
{
cb->valid_pch = c_common_valid_pch;
cb->read_pch = cb_read_pch;
}
if (flag_dump_macros == 'N' || flag_dump_macros == 'D') if (flag_dump_macros == 'N' || flag_dump_macros == 'D')
{ {
cb->define = cb_define; cb->define = cb_define;
...@@ -416,3 +424,17 @@ dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED) ...@@ -416,3 +424,17 @@ dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
return 1; return 1;
} }
/* Load in the PCH file NAME, open on FD. It was originally searched for
by ORIG_NAME. Also, print out a #include command so that the PCH
file can be loaded when the preprocessed output is compiled. */
static void
cb_read_pch (cpp_reader *pfile, const char *name,
int fd, const char *orig_name ATTRIBUTE_UNUSED)
{
c_common_read_pch (pfile, name, fd, orig_name);
fprintf (print.outf, "#pragma GCC pch_preprocess \"%s\"\n", name);
print.src_line++;
}
...@@ -589,6 +589,8 @@ init_pragma (void) ...@@ -589,6 +589,8 @@ init_pragma (void)
c_register_pragma (0, "redefine_extname", handle_pragma_redefine_extname); c_register_pragma (0, "redefine_extname", handle_pragma_redefine_extname);
c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix); c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
c_register_pragma ("GCC", "pch_preprocess", c_common_pch_pragma);
#ifdef REGISTER_TARGET_PRAGMAS #ifdef REGISTER_TARGET_PRAGMAS
REGISTER_TARGET_PRAGMAS (); REGISTER_TARGET_PRAGMAS ();
#endif #endif
......
...@@ -599,6 +599,10 @@ Enable optional diagnostics ...@@ -599,6 +599,10 @@ Enable optional diagnostics
fpch-deps fpch-deps
C ObjC C++ ObjC++ C ObjC C++ ObjC++
fpch-preprocess
C ObjC C++ ObjC++
Look for and use PCH files even when preprocessing
fpermissive fpermissive
C++ ObjC++ C++ ObjC++
Downgrade conformance errors to warnings Downgrade conformance errors to warnings
......
...@@ -323,6 +323,24 @@ precompiled header would be listed and not the files that were used to ...@@ -323,6 +323,24 @@ precompiled header would be listed and not the files that were used to
create it because those files are not consulted when a precompiled create it because those files are not consulted when a precompiled
header is used. header is used.
@item -fpch-preprocess
@opindex fpch-preprocess
This option allows use of a precompiled header (@pxref{Precompiled
Headers}) together with @option{-E}. It inserts a special @code{#pragma},
@code{#pragma GCC pch_preprocess "<filename>"} in the output to mark
the place where the precompiled header was found, and its filename. When
@code{-fpreprocessed} is in use, GCC recognizes this @code{#pragma} and
loads the PCH.
This option is off by default, because the resulting preprocessed output
is only really suitable as input to GCC. It is switched on by
@option{-save-temps}.
You should not write this @code{#pragma} in your own code, but it is
safe to edit the filename if the PCH file is available in a different
location. The filename may be absolute or it may be relative to GCC's
current directory.
@end ifclear @end ifclear
@item -x c @item -x c
@itemx -x c++ @itemx -x c++
......
...@@ -11809,7 +11809,7 @@ which options are safe to change and which are not; the safest choice ...@@ -11809,7 +11809,7 @@ which options are safe to change and which are not; the safest choice
is to use exactly the same options when generating and using the is to use exactly the same options when generating and using the
precompiled header. The following are known to be safe: precompiled header. The following are known to be safe:
@gccoptlist{-pedantic-errors} @gccoptlist{-fpreprocessed -pedantic-errors}
@end itemize @end itemize
...@@ -11819,6 +11819,12 @@ find an option combination that doesn't work and doesn't cause the ...@@ -11819,6 +11819,12 @@ find an option combination that doesn't work and doesn't cause the
precompiled header to be ignored, please consider filing a bug report, precompiled header to be ignored, please consider filing a bug report,
see @ref{Bugs}. see @ref{Bugs}.
If you do use differing options when generating and using the
precompiled header, the actual behaviour will be a mixture of the
behaviour for the options. For instance, if you use @option{-g} to
generate the precompiled header but not when using it, you may or may
not get debugging information for routines in the precompiled header.
@node Running Protoize @node Running Protoize
@section Running Protoize @section Running Protoize
......
...@@ -783,7 +783,8 @@ static const char *cpp_unique_options = ...@@ -783,7 +783,8 @@ static const char *cpp_unique_options =
in turn cause preprocessor symbols to be defined specially. */ in turn cause preprocessor symbols to be defined specially. */
static const char *cpp_options = static const char *cpp_options =
"%(cpp_unique_options) %1 %{m*} %{std*} %{ansi} %{W*&pedantic*} %{w} %{f*}\ "%(cpp_unique_options) %1 %{m*} %{std*} %{ansi} %{W*&pedantic*} %{w} %{f*}\
%{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef}"; %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef}\
%{save-temps:-fpch-preprocess}";
/* This contains cpp options which are not passed when the preprocessor /* This contains cpp options which are not passed when the preprocessor
output will be used by another program. */ output will be used by another program. */
......
2004-06-21 Geoffrey Keating <geoffk@apple.com>
* gcc.dg/pch/save-temps-1.c: New file.
* gcc.dg/pch/save-temps-1.hs: New file.
2004-06-22 Janne Blomqvist <jblomqvi@cc.hut.fi> 2004-06-22 Janne Blomqvist <jblomqvi@cc.hut.fi>
* gfortran.fortran-torture/execute/iolength_1.f90: New test. * gfortran.fortran-torture/execute/iolength_1.f90: New test.
......
/* { dg-options "-I. -save-temps" } */
#include "save-temps-1.h"
#ifndef T
#error T not defined
#endif
#include <stddef.h>
int x;
#define T 123
int foo (void)
{
return 3;
}
2004-06-21 Geoffrey Keating <geoffk@apple.com>
* files.c (should_stack_file): Correct swapped parameters to call
to cb.read_pch.
* pch.c (cpp_valid_state): Handle -fpreprocessed.
2004-06-15 Paolo Bonzini <bonzini@gnu.org> 2004-06-15 Paolo Bonzini <bonzini@gnu.org>
* Makefile.in: Regenerate with automake 1.8.5. * Makefile.in: Regenerate with automake 1.8.5.
......
...@@ -625,7 +625,7 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) ...@@ -625,7 +625,7 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
/* Handle PCH files immediately; don't stack them. */ /* Handle PCH files immediately; don't stack them. */
if (file->pch) if (file->pch)
{ {
pfile->cb.read_pch (pfile, file->path, file->fd, file->pchname); pfile->cb.read_pch (pfile, file->pchname, file->fd, file->path);
close (file->fd); close (file->fd);
file->fd = -1; file->fd = -1;
return false; return false;
......
...@@ -438,13 +438,22 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd) ...@@ -438,13 +438,22 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
if (m.name_length == 0) if (m.name_length == 0)
break; break;
/* If this file is already preprocessed, there won't be any
macros defined, and that's OK. */
if (CPP_OPTION (r, preprocessed))
{
if (lseek (fd, m.definition_length, SEEK_CUR) == -1)
goto error;
continue;
}
if (m.definition_length > namebufsz) if (m.definition_length > namebufsz)
{ {
free (namebuf); free (namebuf);
namebufsz = m.definition_length + 256; namebufsz = m.definition_length + 256;
namebuf = xmalloc (namebufsz); namebuf = xmalloc (namebufsz);
} }
if ((size_t)read (fd, namebuf, m.definition_length) if ((size_t)read (fd, namebuf, m.definition_length)
!= m.definition_length) != m.definition_length)
goto error; goto error;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment