diff mbox

[pph] New PPH command line and tests

Message ID AANLkTinrv8BqMbgfb7OPCfOKGaEAXDxt-PZb31tpcwU1@mail.gmail.com
State New
Headers show

Commit Message

Lawrence Crowl Feb. 17, 2011, 12:03 a.m. UTC
This pre-parsed-header patch adds new options to support command-line
driven PPH.  A header file foo.h that is to be pre-parsed is
compiled with

    -x c++-header -o foo.pph

The output file extension distinguishes a PPH compilation from a
pre-compiled header (PCH) compilation.

A compilation using pre-parsed headers, must provide a mapping
from #include file to pph file names.  The simplest option is
-fpph-hdr=<basename>, which maps <basename>.h to <basename>.pph.
The general option is -fpph-map=<filename>, which reads mapping from
a file.  The format of the file is a sequence of lines of the form
"<headername><tab><pphfilename>".

This patch provides commandline and testing infrastructure, but
does not itself implement any functionality.  The currently writes
dummy PPH files.  When reading, it verifies the contents and then
processes the #include normally.  This approach enables working
tests now, and working tests when we are finished.

To support PPH mapping, I've added strstrmap.[hc] supporting a
string-to-string mapping.

The pre-tokenized header (PTH) tests that are currently in
the gcc/testsuite/pph directory have been rewritten to the new
command-line-driven scheme.  In the process, I've renamed tests to
the following conventions in the prefix of the name.

    [acdpxy][12]*
    a - auxillary headers
    c - positive tests for c-level headers and sources
    d - negative tests for c-level headers and sources
    p - positive tests for what would be c-level code, but which
        due to C++ standard namespace games are not quite C level
        tests.
    x - C++-level positive tests.
    y - C++-level negative tests.
    1 - first priority feature tests
    2 - second priority feature tests

To support PPH testing, I've added a new "preparse" compilation
type to lib/gcc-dg.exp and substantially rewritten lib/dg-pph.exp.


Index: gcc/testsuite/ChangeLog.pph

2011-02-15  Lawrence Crowl <crowl@google.com>

	* lib/dg-pph.exp: Restructure for command-driven PPH.
	* lib/gcc-dg.exp (gcc-dg-test-1): Add "preparse" compilation type.
	* g++.dg/pph/a2builtin4.h: Add.
	* g++.dg/pph/autometh.cc: Remove.
	* g++.dg/pph/builtin.cc: Remove.
	* g++.dg/pph/builtin1.h: Remove.
	* g++.dg/pph/builtin2.h: Remove.
	* g++.dg/pph/builtin3.h: Remove.
	* g++.dg/pph/c1altinc.cc: Add.
	* g++.dg/pph/c1altinc1.h: Add.
	* g++.dg/pph/c1altinc2.h: Add.
	* g++.dg/pph/c1chained1.h: Add.
	* g++.dg/pph/c1chained2.h: Add.
	* g++.dg/pph/c1empty.cc: Add.
	* g++.dg/pph/c1empty.h: Add.
	* g++.dg/pph/c1field.cc: Add.
	* g++.dg/pph/c1field.h: Add.
	* g++.dg/pph/c1funcmac.cc: Add.
	* g++.dg/pph/c1funcmac.h: Add.
	* g++.dg/pph/c1functions.cc: Add.
	* g++.dg/pph/c1functions.h: Add.
	* g++.dg/pph/c1guarded.cc: Add.
	* g++.dg/pph/c1guarded1.h: Add.
	* g++.dg/pph/c1guarded2.h: Add.
	* g++.dg/pph/c1guarded3.h: Add.
	* g++.dg/pph/c1multinc.cc: Add.
	* g++.dg/pph/c1multinc1.h: Add.
	* g++.dg/pph/c1multinc2.h: Add.
	* g++.dg/pph/c1simple.cc: Add.
	* g++.dg/pph/c1simple1.h: Add.
	* g++.dg/pph/c1simple2.h: Add.
	* g++.dg/pph/c1struct.cc: Add.
	* g++.dg/pph/c1struct.h: Add.
	* g++.dg/pph/c1typerefs.cc: Add.
	* g++.dg/pph/c1typerefs.h: Add.
	* g++.dg/pph/c1variables.cc: Add.
	* g++.dg/pph/c1variables.h: Add.
	* g++.dg/pph/c2builtin1.cc: Add.
	* g++.dg/pph/c2builtin1.h: Add.
	* g++.dg/pph/c2builtin2.cc: Add.
	* g++.dg/pph/c2builtin2.h: Add.
	* g++.dg/pph/c2builtin3.h: Add.
	* g++.dg/pph/c2builtin5.h: Add.
	* g++.dg/pph/c2builtin6.h: Add.
	* g++.dg/pph/c2dupguard1.h: Add.
	* g++.dg/pph/c2dupguard2.h: Add.
	* g++.dg/pph/c2paste.cc: Add.
	* g++.dg/pph/c2paste.h: Add.
	* g++.dg/pph/cflow.cc: Remove.
	* g++.dg/pph/cflow.h: Remove.
	* g++.dg/pph/chained.cc: Remove.
	* g++.dg/pph/chained1.h: Remove.
	* g++.dg/pph/chained2.h: Remove.
	* g++.dg/pph/classshort.cc: Remove.
	* g++.dg/pph/d1chained.cc: Add.
	* g++.dg/pph/d1symnotinc.cc: Add.
	* g++.dg/pph/d1symnotinc.h: Add.
	* g++.dg/pph/d2dupguard.cc: Add.
	* g++.dg/pph/d2null.h: Add.
	* g++.dg/pph/emptyclass.cc: Remove.
	* g++.dg/pph/field.cc: Remove.
	* g++.dg/pph/funcstatic.cc: Remove.
	* g++.dg/pph/functions.cc: Remove.
	* g++.dg/pph/globalref.cc: Remove.
	* g++.dg/pph/guarded.cc: Remove.
	* g++.dg/pph/guarded1.h: Remove.
	* g++.dg/pph/guarded2.h: Remove.
	* g++.dg/pph/guarded3.h: Remove.
	* g++.dg/pph/hardlookup.cc: Remove.
	* g++.dg/pph/incmod.cc: Remove.
	* g++.dg/pph/incmod.h: Remove.
	* g++.dg/pph/incsame.cc: Remove.
	* g++.dg/pph/incsame.h: Remove.
	* g++.dg/pph/inif.h: Remove.
	* g++.dg/pph/invoke.cc: Remove.
	* g++.dg/pph/invoke.h: Remove.
	* g++.dg/pph/mean.cc: Remove.
	* g++.dg/pph/meth.cc: Remove.
	* g++.dg/pph/meth2.cc: Remove.
	* g++.dg/pph/nontrivinit.cc: Remove.
	* g++.dg/pph/p1mean.cc: Add.
	* g++.dg/pph/p1stdlib.cc: Add.
	* g++.dg/pph/p1systypes.cc: Add.
	* g++.dg/pph/paste.cc: Remove.
	* g++.dg/pph/pph.exp: Add.
	* g++.dg/pph/pph.map: Add.
	* g++.dg/pph/simple.cc: Remove.
	* g++.dg/pph/simple1.h: Remove.
	* g++.dg/pph/simple2.h: Remove.
	* g++.dg/pph/simplecall.cc: Remove.
	* g++.dg/pph/special.cc: Remove.
	* g++.dg/pph/staticmbrvar.cc: Remove.
	* g++.dg/pph/sys-types.cc: Remove.
	* g++.dg/pph/system-include.cc: Remove.
	* g++.dg/pph/template.cc: Remove.
	* g++.dg/pph/tmplclass.cc: Remove.
	* g++.dg/pph/tmplfunc.cc: Remove.
	* g++.dg/pph/tmplsimple.cc: Remove.
	* g++.dg/pph/trivial.cc: Remove.
	* g++.dg/pph/typerefs.cc: Remove.
	* g++.dg/pph/usearray.cc: Remove.
	* g++.dg/pph/usearray.h: Remove.
	* g++.dg/pph/variable.cc: Remove.
	* g++.dg/pph/variables.cc: Remove.
	* g++.dg/pph/where.cc: Remove.
	* g++.dg/pph/x1autometh.cc: Add.
	* g++.dg/pph/x1autometh.h: Add.
	* g++.dg/pph/x1funcstatic.cc: Add.
	* g++.dg/pph/x1funcstatic.h: Add.
	* g++.dg/pph/x1functions.cc: Add.
	* g++.dg/pph/x1functions.h: Add.
	* g++.dg/pph/x1globalref.cc: Add.
	* g++.dg/pph/x1globalref.h: Add.
	* g++.dg/pph/x1hardlookup.cc: Add.
	* g++.dg/pph/x1hardlookup.h: Add.
	* g++.dg/pph/x1special.cc: Add.
	* g++.dg/pph/x1special.h: Add.
	* g++.dg/pph/x1struct0.h: Add.
	* g++.dg/pph/x1struct1.cc: Add.
	* g++.dg/pph/x1struct1.h: Add.
	* g++.dg/pph/x1struct2.cc: Add.
	* g++.dg/pph/x1struct2.h: Add.
	* g++.dg/pph/x1template.cc: Add.
	* g++.dg/pph/x1template.h: Add.
	* g++.dg/pph/x1tmplclass.cc: Add.
	* g++.dg/pph/x1tmplclass.h: Add.
	* g++.dg/pph/x1tmplfunc.cc: Add.
	* g++.dg/pph/x1tmplfunc.h: Add.
	* g++.dg/pph/x1typerefs.cc: Add.
	* g++.dg/pph/x1typerefs.h: Add.
	* g++.dg/pph/x1variables.cc: Add.
	* g++.dg/pph/x1variables.h: Add.
	* g++.dg/pph/x2nontrivinit.cc: Add.
	* g++.dg/pph/x2nontrivinit.h: Add.
	* g++.dg/pph/x2overload1.h: Add.
	* g++.dg/pph/x2overload2.h: Add.
	* g++.dg/pph/x2overload3.h: Add.
	* g++.dg/pph/y2overload.cc: Add.


Index: gcc/cp/ChangeLog.pph

2011-02-15  Lawrence Crowl <crowl@google.com>

        * cp/pph.c (write_pph_output, read_pph_file,
        pph_include_handler): Add.
	(pph_start_exposed, pph_stop_exposed): Change debug level.
	(pph_init): Set callback for pph_include_handler.
	(pph_finish): Write PPH file.
        * cp/parser.c (cp_lexer_new_main): Duplicate PTH and PCH
        incompatibility for PPH.  Add call to pph_init only when PPH
        is being used.
	* (c_parse_file): Remove call to pph_init.

Index: gcc/ChangeLog.pph

2011-02-15  Lawrence Crowl <crowl@google.com>

	* strstrmap.h: Add.
	* strstrmap.c: Add.
	* c-family/c-common.h (pph_out_file, query_have_pph_map,
	query_pph_include_map): Add declarations.
	* c-family/c-common.c (pph_out_file): Add definition.
	* c-family/c.opt: Add flags -fpph-hdr= and -fpph-map=.
	* c-family/c-opts.c (query_have_pph_map, add_pph_header_map,
	query_pph_include_map): Add definitions.
	(c_common_handle_option): Detect when an output file is PPH.
	Handle flags -fpph-hdr= and -fpph-map=.
	* Makefile.in:
	Add rule for strstrmap.o.
	Add strstrmap.o to C_COMMON_OBJS.
	Add dependence of c-family/c-opts.o on strstrmap.h.

Comments

Diego Novillo Feb. 17, 2011, 2:37 p.m. UTC | #1
On 11-02-16 07:03 PM, Lawrence Crowl wrote:

> The pre-tokenized header (PTH) tests that are currently in
> the gcc/testsuite/pph directory have been rewritten to the new
> command-line-driven scheme.  In the process, I've renamed tests to
> the following conventions in the prefix of the name.
>
>      [acdpxy][12]*
>      a - auxillary headers
>      c - positive tests for c-level headers and sources
>      d - negative tests for c-level headers and sources
>      p - positive tests for what would be c-level code, but which
>          due to C++ standard namespace games are not quite C level
>          tests.
>      x - C++-level positive tests.
>      y - C++-level negative tests.
>      1 - first priority feature tests
>      2 - second priority feature tests

Could you add a README file in g++.dg/pph documenting this convention? 
You rely on tcl expansion ordering to get at these files in the proper 
order, right?


> Index: gcc/strstrmap.c
> ===================================================================
> *** gcc/strstrmap.c	(revision 0)
> --- gcc/strstrmap.c	(revision 0)
> ***************
> *** 0 ****
> --- 1,181 ----
> + /* A string to string mapping.
> +
> +    Copyright (C) 2011 Free Software Foundation, Inc.
> +    Contributed by Lawrence Crowl <crowl@google.com> and
> +    Diego Novillo <dnovillo@google.com>.

I had nothing to do with this :)

> + /* A string to string mapping.
> +
> +    Copyright (C) 2011 Free Software Foundation, Inc.
> +    Contributed by Lawrence Crowl <crowl@google.com> and
> +    Diego Novillo <dnovillo@google.com>.

Likewise.


> +
> +   length = strlen (basename);
> +   strcpy (hdrbuf, basename);
> +   strcpy (hdrbuf+length, ".h");

Space around '+'.

> +   strcpy (pphbuf, basename);
> +   strcpy (pphbuf+length, ".pph");

Likewise.

> +   old_file = strstrmap_insert (include_pph_mapping, hdrbuf, pphbuf);
> +   if (old_file != NULL)
> +     {
> +       /* FIXME pph: free (CONST_CAST (void*, old_file)); */
> +       fatal_error ("PPH include %s was remapped: ", pphbuf);

What's this FIXME?  You're about to fatal_error, freeing memory is not 
really important.

> +       include = line;
> +       pph_file = tab+1;

space around '+'.

> +       old_file = strstrmap_insert (include_pph_mapping, include, pph_file);
> +       if (old_file != NULL)
> +         {
> +           /* FIXME pph: free (CONST_CAST (void*, old_file)); */
> +           fatal_error ("PPH include %s was remapped: ", include);

Same as before.


> --- 1154,1160 ----
>   # Language-specific object files shared by all C-family front ends.
>   C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
>     c-family/c-format.o c-family/c-gimplify.o c-family/c-lex.o \
> !   c-family/c-omp.o strstrmap.o c-family/c-opts.o c-family/c-pch.o \
>     c-family/c-ppoutput.o c-family/c-pragma.o c-family/c-pretty-print.o \
>     c-family/c-semantics.o c-family/c-ada-spec.o

strstrmap.o should be in OBJS-common, actually.

Looks OK otherwise.

I'm currently finishing the move to use the LTO streamer to write out 
trees from the front end.  To test it out, I will hook it to -fpth to 
write the few trees produced during pre-tokenization.  So, I've added a 
pth testsuite directory and a dg-pth.exp.

Once I have that working, you can start using it to emit/read trees from 
pph.  We can decide later what to do with the pre-tokenization code.


Diego.
diff mbox

Patch

Index: gcc/strstrmap.c
===================================================================
*** gcc/strstrmap.c	(revision 0)
--- gcc/strstrmap.c	(revision 0)
***************
*** 0 ****
--- 1,181 ----
+ /* A string to string mapping.
+ 
+    Copyright (C) 2011 Free Software Foundation, Inc.
+    Contributed by Lawrence Crowl <crowl@google.com> and
+    Diego Novillo <dnovillo@google.com>.
+ 
+    This file is part of GCC.
+ 
+    GCC 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 3, or (at your option)
+    any later version.
+ 
+    GCC 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 GCC; see the file COPYING3.  If not see
+ <http://www.gnu.org/licenses/>.  */
+ 
+ #include "config.h"
+ #include "system.h"
+ #include "coretypes.h"
+ 
+ #include "libiberty.h"
+ #include "hashtab.h"
+ 
+ #include "strstrmap.h"
+ 
+ /* The hash table slot type.  */
+ 
+ typedef struct strstrhashslot_d
+ {
+   const char *key;
+   const char *val;
+ } strstrhashslot_t;
+ 
+ /* Returns a hash code for the slot v.
+    Function type is typedef hashval_t (*htab_hash) (const void *);  */
+ 
+ static hashval_t
+ strstrhashslot_hash (const void *v)
+ {
+   const strstrhashslot_t *s = (const strstrhashslot_t *) v;
+   return htab_hash_string (s->key);
+ }
+ 
+ /* Compares two slots, V1 and V2, for equality.
+    Function type is typedef int (*htab_eq) (const void *, const void *);  */
+ 
+ static int
+ strstrhashslot_eq (const void *v1, const void *v2)
+ {
+   const strstrhashslot_t *s1 = (const strstrhashslot_t *) v1;
+   const strstrhashslot_t *s2 = (const strstrhashslot_t *) v2;
+   return strcmp (s1->key, s2->key) == 0;
+ }
+ 
+ /* Free the slot V.  */
+ 
+ static void
+ strstrhashslot_free (void *v)
+ {
+   strstrhashslot_t *s = (strstrhashslot_t *) v;
+   free (CONST_CAST (void *, (const void *) s->key));
+   free (CONST_CAST (void *, (const void *) s->val));
+   free (v);
+ }
+ 
+ /* The type for the hash table itself.  */
+ 
+ struct strstrmap_d
+ {
+   htab_t tab;
+ };
+ 
+ /* Create a hash table.  */
+ 
+ strstrmap_t*
+ strstrmap_create (void)
+ {
+   strstrmap_t *tbl;
+   htab_t tab;
+   tbl = XCNEW (strstrmap_t);
+   gcc_assert (tbl != NULL);
+   tab = htab_create (37, strstrhashslot_hash,
+                      strstrhashslot_eq, strstrhashslot_free);
+   gcc_assert (tab != NULL);
+   tbl->tab = tab;
+   return tbl;
+ }
+ 
+ /* Destroy the hash table TBL.  */
+ 
+ void
+ strstrmap_destroy (strstrmap_t *tbl)
+ {
+   htab_delete (tbl->tab);
+   free (tbl);
+ }
+ 
+ /* Insert a mapping from KEY to VAL into hash table TBL.
+    All parameters must not be NULL.
+    If the KEY is new, the insert returns NULL.
+    If the KEY is not new, the insert returns the old VAL,
+    which has been replaced.
+    The caller owns any storage that the return value points to.  */
+ 
+ const char*
+ strstrmap_insert (strstrmap_t *tbl, const char *key, const char *val)
+ {
+   strstrhashslot_t query;
+   strstrhashslot_t **spot;
+   const char* result;
+ 
+   gcc_assert (tbl != NULL);
+   gcc_assert (key != NULL);
+   gcc_assert (val != NULL);
+ 
+   query.key = key;
+   query.val = val;
+   spot = (strstrhashslot_t **) htab_find_slot (tbl->tab, &query, INSERT);
+ 
+   if (*spot == NULL)
+     {
+       /* We found no instance of key in the table.  */
+       strstrhashslot_t *entry
+           = (strstrhashslot_t *) xmalloc (sizeof (strstrhashslot_t));
+       entry->key = xstrdup (key);
+       entry->val = xstrdup (val);
+       *spot = entry;
+       result = NULL;
+     }
+   else
+     {
+       /* We found an instance of key already in the table.  */
+       strstrhashslot_t *entry = (strstrhashslot_t *)*spot;
+       result = entry->val;
+       entry->val = xstrdup (val);
+     }
+ 
+   return result;
+ }
+ 
+ /* Lookup a mapping for KEY in hash table TBL.
+    All parameters must not be NULL.
+    If the KEY is new, the insert returns NULL.
+    If the KEY is not new, the insert returns the old VAL,
+    which has been replaced.
+    The caller does NOT owns any storage that the return value points to.  */
+ 
+ const char*
+ strstrmap_lookup (strstrmap_t* tbl, const char* key)
+ {
+   strstrhashslot_t query;
+   strstrhashslot_t **spot;
+   const char* result;
+ 
+   gcc_assert (tbl != NULL);
+   gcc_assert (key != NULL);
+ 
+   query.key = key;
+   spot = (strstrhashslot_t **) htab_find_slot (tbl->tab, &query, NO_INSERT);
+ 
+   if (spot == NULL)
+     {
+       /* We found no instance of key in the table.  */
+       result = NULL;
+     }
+   else
+     {
+       /* We found an instance of key in the table.  */
+       strstrhashslot_t *entry = (strstrhashslot_t *)*spot;
+       gcc_assert (entry != NULL);
+       result = entry->val;
+     }
+ 
+   return result;
+ }
Index: gcc/strstrmap.h
===================================================================
*** gcc/strstrmap.h	(revision 0)
--- gcc/strstrmap.h	(revision 0)
***************
*** 0 ****
--- 1,29 ----
+ /* A string to string mapping. 
+ 
+    Copyright (C) 2011 Free Software Foundation, Inc.
+    Contributed by Lawrence Crowl <crowl@google.com> and
+    Diego Novillo <dnovillo@google.com>.
+    
+    This file is part of GCC.
+ 
+    GCC 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 3, or (at your option)
+    any later version.
+ 
+    GCC 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 GCC; see the file COPYING3.  If not see
+ <http://www.gnu.org/licenses/>.  */
+ 
+ typedef struct strstrmap_d strstrmap_t;
+ 
+ extern strstrmap_t* strstrmap_create (void);
+ extern void strstrmap_destroy (strstrmap_t *tbl);
+ extern const char* strstrmap_insert (strstrmap_t *tbl, const char *key,
+                                      const char *val);
+ extern const char* strstrmap_lookup (strstrmap_t *tbl, const char *key);
Index: gcc/c-family/c.opt
===================================================================
*** gcc/c-family/c.opt	(revision 170223)
--- gcc/c-family/c.opt	(working copy)
*************** fpph
*** 913,918 ****
--- 913,926 ----
  C++ Var(flag_pph)
  -fpph   Enable pre-parsed header (PPH) support
  
+ fpph-hdr=
+ C++ ObjC++ Joined MissingArgError(missing filename after %qs)
+ -fpph-hdr=<base-name>   A mapping from <base-name>.h to <base-name>.pph
+ 
+ fpph-map=
+ C++ ObjC++ Joined MissingArgError(missing filename after %qs)
+ -fpph-map=<file-name>   A file of mappings from #include to PPH file
+ 
  fpph-debug=
  C++ Joined RejectNegative UInteger Var(flag_pph_debug)
  -fpph-debug=N   Enable debugging output at level N from PPH support
Index: gcc/c-family/c-opts.c
===================================================================
*** gcc/c-family/c-opts.c	(revision 170223)
--- gcc/c-family/c-opts.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 38,43 ****
--- 38,44 ----
  #include "mkdeps.h"
  #include "target.h"		/* For gcc_targetcm.  */
  #include "tm_p.h"		/* For C_COMMON_OVERRIDE_OPTIONS.  */
+ #include "strstrmap.h"
  
  #ifndef DOLLARS_IN_IDENTIFIERS
  # define DOLLARS_IN_IDENTIFIERS true
*************** static void c_finish_options (void);
*** 122,127 ****
--- 123,223 ----
  #define STDC_0_IN_SYSTEM_HEADERS 0
  #endif
  
+ /* Mappings from include directive to PPH file.  */
+ 
+ strstrmap_t *include_pph_mapping;
+ 
+ /* Query if we have any map from INCLUDE to PPH file.  */
+ 
+ bool
+ query_have_pph_map (void)
+ {
+   return include_pph_mapping != NULL;
+ }
+ 
+ /* Add mappings from include directive to PPH files found within file FILENAME.
+    The file is a sequence of lines.
+    Each line contains the directive, followed by a tab,
+    and finally followed by the filename.  */
+ 
+ static void
+ add_pph_header_map (const char *basename)
+ {
+   int length;
+   const char* old_file;
+   char hdrbuf[MAXPATHLEN];
+   char pphbuf[MAXPATHLEN];
+ 
+   length = strlen (basename);
+   strcpy (hdrbuf, basename);
+   strcpy (hdrbuf+length, ".h");
+   strcpy (pphbuf, basename);
+   strcpy (pphbuf+length, ".pph");
+   old_file = strstrmap_insert (include_pph_mapping, hdrbuf, pphbuf);
+   if (old_file != NULL)
+     {
+       /* FIXME pph: free (CONST_CAST (void*, old_file)); */
+       fatal_error ("PPH include %s was remapped: ", pphbuf);
+     }
+ }
+ 
+ /* Add mappings from include directive to PPH files found within file FILENAME.
+    The file is a sequence of lines.
+    Each line contains the directive, followed by a tab,
+    and finally followed by the filename.  */
+ 
+ static void
+ add_pph_include_maps (const char *filename)
+ {
+   FILE* stream;
+   char *line;
+   char linebuf[2*MAXPATHLEN];
+ 
+   if (include_pph_mapping == NULL)
+     include_pph_mapping = strstrmap_create ();
+ 
+   stream = fopen (filename, "r");
+   if (!stream)
+     fatal_error ("Cannot open %s for reading: %m", filename);
+   
+   line = fgets (linebuf, sizeof linebuf, stream);
+   while (line != NULL)
+     {
+       char *eol, *tab;
+       const char *include, *pph_file, *old_file;
+       eol = strchr (line, '\n');
+       tab = strchr (line, '\t');
+       if (eol == NULL || tab == NULL)
+         fatal_error ("Ill-formed PPH mapping file %s: ", filename);
+       *eol = '\0';
+       *tab = '\0';
+       include = line;
+       pph_file = tab+1;
+       old_file = strstrmap_insert (include_pph_mapping, include, pph_file);
+       if (old_file != NULL)
+         {
+           /* FIXME pph: free (CONST_CAST (void*, old_file)); */
+           fatal_error ("PPH include %s was remapped: ", include);
+         }
+       line = fgets (linebuf, sizeof linebuf, stream);
+     }
+ 
+     fclose (stream);
+ }
+ 
+ /* Query for a mappings from an INCLUDE to a PPH file.
+    Return the filename, without ownership.
+    If there is no mapping, return null.  */
+ 
+ const char *
+ query_pph_include_map (const char *include)
+ {
+   if (include_pph_mapping == NULL)
+     return NULL;
+   else
+     return strstrmap_lookup (include_pph_mapping, include);
+ }
+ 
  /* Holds switches parsed by c_common_handle_option (), but whose
     handling is deferred to c_common_post_options ().  */
  static void defer_opt (enum opt_code, const char *);
*************** c_common_handle_option (size_t scode, co
*** 266,272 ****
        break;
  
      case OPT__output_pch_:
!       pch_file = arg;
        break;
  
      case OPT_A:
--- 362,374 ----
        break;
  
      case OPT__output_pch_:
!       {
!         char *dot = strrchr (arg, '.');
!         if (dot != NULL && strcmp (dot, ".pph") == 0)
!           pph_out_file = arg;
!         else
!           pch_file = arg;
!       }
        break;
  
      case OPT_A:
*************** c_common_handle_option (size_t scode, co
*** 666,671 ****
--- 768,781 ----
        set_struct_debug_option (&global_options, loc, arg);
        break;
  
+     case OPT_fpph_hdr_:
+       add_pph_header_map (arg);
+       break;
+ 
+     case OPT_fpph_map_:
+       add_pph_include_maps (arg);
+       break;
+ 
      case OPT_idirafter:
        add_path (xstrdup (arg), AFTER, 0, true);
        break;
Index: gcc/c-family/c-common.c
===================================================================
*** gcc/c-family/c-common.c	(revision 170223)
--- gcc/c-family/c-common.c	(working copy)
*************** bool flag_pch_preprocess;
*** 190,195 ****
--- 190,200 ----
  
  const char *pch_file;
  
+ /* The file name to which we should write a preparsed header, or
+    NULL if no header will be written in this compile.  */
+ 
+ const char *pph_out_file;
+ 
  /* Nonzero if an ISO standard was selected.  It rejects macros in the
     user's namespace.  */
  int flag_iso;
Index: gcc/c-family/c-common.h
===================================================================
*** gcc/c-family/c-common.h	(revision 170223)
--- gcc/c-family/c-common.h	(working copy)
*************** extern bool flag_pch_preprocess;
*** 543,548 ****
--- 543,565 ----
  
  extern const char *pch_file;
  
+ /* The file name to which we should write a preparsed header, or
+    NULL if no header will be written in this compile.  */
+ 
+ extern const char *pph_out_file;
+ 
+ /* Query if we have any map from INCLUDE to PPH file.  */
+ 
+ extern bool
+ query_have_pph_map (void);
+ 
+ /* Query for a mapping from an INCLUDE to a PPH file.
+    Return the filename, without ownership.
+    If there is no mapping, return null.  */
+ 
+ extern const char *
+ query_pph_include_map (const char *include);
+ 
  /* Nonzero if an ISO standard was selected.  It rejects macros in the
     user's namespace.  */
  
Index: gcc/testsuite/lib/dg-pph.exp
===================================================================
*** gcc/testsuite/lib/dg-pph.exp	(revision 170223)
--- gcc/testsuite/lib/dg-pph.exp	(working copy)
***************
*** 15,79 ****
  # <http://www.gnu.org/licenses/>.
  
  # Contributed by Diego Novillo <dnovillo@google.com>
  
  load_lib copy-file.exp
  
! proc dg-flags-pph { subdir test otherflags options suffix } {
      global runtests dg-do-what-default
  
      # If we're only testing specific files and this isn't one of them, skip it.
      if ![runtest_file_p $runtests $test] {
  	return
      }
      set nshort "$subdir/[file tail $test]"
      set bname "[file rootname [file tail $nshort]]"
  
!     foreach flags $options {
! 	verbose "Testing $nshort, $otherflags $flags" 1
  
! 	set dg-do-what-default compile
  
! 	set have_errs [llength [grep $test "{\[ \t\]\+dg-error\[ \t\]\+.*\[ \t\]\+}"]]
! 	# Compile the file the first time to produce PPH/PTH images.
! 	dg-test -keep-output $test "$otherflags $flags -I." ""
! 
! 	if { !$have_errs } {
! 	    if { [ file_on_host exists "$bname.s" ] } {
! 		# Rename the .s file into .s-pph to compare it after the
! 		# second build.
! 		remote_upload host "$bname.s" "$bname.s-pph"
! 		remote_download host "$bname.s-pph"
! 
! 		# Compile a second time to use the generated images.
! 		dg-test -keep-output $test "$otherflags $flags -I." ""
! 		remote_upload host "$bname.s"
! 
! 		# Compare the two assembly files.  They should be identical.
! 		set tmp [ diff "$bname.s" "$bname.s-pph" ]
! 		if { $tmp == 0 } {
! 		    verbose -log "assembly file '$bname.s', '$bname.s-pph' comparison error"
! 		    fail "$nshort $otherflags $flags assembly comparison"
! 		} elseif { $tmp == 1 } {
! 		    pass "$nshort $otherflags $flags assembly comparison"
! 		} else {
! 		    fail "$nshort $otherflags $flags assembly comparison"
! 		}
! 		file_on_host delete "$bname$suffix"
! 		file_on_host delete "$bname.s"
! 		file_on_host delete "$bname.s-pph"
! 	    } else {
! 		verbose -log "assembly file '$bname.s' missing"
! 		fail "$nshort $flags assembly comparison"
! 	    }
! 	}
! 
! 	# Remove stale .pth files, if any.
! 	foreach pth_file [glob -nocomplain *.pth] {
! 	    file_on_host delete $pth_file
! 	}
      }
  }
  
! proc dg-pph { subdir test options suffix } {
!   return [dg-flags-pph $subdir $test "" $options $suffix]
  }
--- 15,107 ----
  # <http://www.gnu.org/licenses/>.
  
  # Contributed by Diego Novillo <dnovillo@google.com>
+ # Adapted to new command-driven scheme by Lawrence Crowl <crowl@google.com>
  
  load_lib copy-file.exp
  
! proc dg-pph-hdr { subdir test options mapflag suffix } {
! 
      global runtests dg-do-what-default
  
      # If we're only testing specific files and this isn't one of them, skip it.
      if ![runtest_file_p $runtests $test] {
  	return
      }
+ 
      set nshort "$subdir/[file tail $test]"
      set bname "[file rootname [file tail $nshort]]"
+     verbose "Testing $nshort, $options" 1
+     set dg-do-what-default preparse
+     dg-test -keep-output $test "$options $mapflag -I." ""
  
! }
  
! proc dg-pph-neg { subdir test options mapflag suffix } {
  
!     global runtests dg-do-what-default
! 
!     # If we're only testing specific files and this isn't one of them, skip it.
!     if ![runtest_file_p $runtests $test] {
! 	return
      }
+ 
+     set nshort "$subdir/[file tail $test]"
+     set bname "[file rootname [file tail $nshort]]"
+     verbose "Testing $nshort, $options" 1
+     set dg-do-what-default compile
+     dg-test -keep-output $test "$options $mapflag -I." ""
+     file_on_host delete "$bname.s"
  }
  
! proc dg-pph-pos { subdir test options mapflag suffix } {
! 
!     global runtests dg-do-what-default
! 
!     # If we're only testing specific files and this isn't one of them, skip it.
!     if ![runtest_file_p $runtests $test] {
! 	return
!     }
! 
!     set nshort "$subdir/[file tail $test]"
!     set bname "[file rootname [file tail $nshort]]"
!     verbose "Testing $nshort, $options" 1
!     set dg-do-what-default compile
! 
!     set have_errs [llength [grep $test "{\[ \t\]\+dg-error\[ \t\]\+.*\[ \t\]\+}"]]
!     # Compile the file the first time for a base case.
!     dg-test -keep-output $test "$options -I." ""
! 
!     if { $have_errs } {
! 	verbose -log "regular compilation failed"
! 	fail "$nshort $options, regular compilation failed"
!         return
!     }
! 
!     if { ! [ file_on_host exists "$bname.s" ] } {
! 	verbose -log "assembly file '$bname.s' missing"
! 	fail "$nshort $options, assembly comparison"
!         return
!     }
! 
!     # Rename the .s file into .s-pph to compare it after the second build.
!     remote_upload host "$bname.s" "$bname.s-pph"
!     remote_download host "$bname.s-pph"
! 
!     # Compile a second time using the pph files.
!     dg-test -keep-output $test "$options $mapflag -I." ""
!     remote_upload host "$bname.s"
! 
!     # Compare the two assembly files.  They should be identical.
!     set tmp [ diff "$bname.s" "$bname.s-pph" ]
!     if { $tmp == 0 } {
!         verbose -log "assembly file '$bname.s', '$bname.s-pph' comparison error"
!         fail "$nshort $options assembly comparison"
!     } elseif { $tmp == 1 } {
!         pass "$nshort $options assembly comparison"
!     } else {
!         fail "$nshort $options assembly comparison"
!     }
!     file_on_host delete "$bname.s"
!     file_on_host delete "$bname.s-pph"
! 
  }
Index: gcc/testsuite/lib/gcc-dg.exp
===================================================================
*** gcc/testsuite/lib/gcc-dg.exp	(revision 170223)
--- gcc/testsuite/lib/gcc-dg.exp	(working copy)
*************** proc gcc-dg-test-1 { target_compile prog
*** 122,127 ****
--- 122,131 ----
  	    set compile_type "precompiled_header"
  	    set output_file "[file tail $prog].gch"
  	}
+ 	"preparse" {
+ 	    set compile_type "preparsed_header"
+ 	    set output_file "[file rootname [file tail $prog]].pph"
+ 	}
  	"link" {
  	    set compile_type "executable"
  	    set output_file "[file rootname [file tail $prog]].exe"
Index: gcc/testsuite/g++.dg/pph/c1altinc.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/c1altinc.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1altinc.cc	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ #include "c1altinc2.h"
+ void foo (void)
+ {
+   int x = var1 + var2 - (int) f1;
+ }
Index: gcc/testsuite/g++.dg/pph/x2nontrivinit.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x2nontrivinit.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x2nontrivinit.h	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ #ifndef X2NONTRIVINIT_H
+ #define X2NONTRIVINIT_H
+ int y = 0;
+ int x = y+1;
+ #endif
Index: gcc/testsuite/g++.dg/pph/c1funcmac.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1funcmac.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1funcmac.h	(revision 0)
***************
*** 0 ****
--- 1,7 ----
+ #ifndef C1FUNCMAC_H
+ #define C1FUNCMAC_H
+ #define gnu_dev_major(dev) long dev
+ #define gnu_dev_minor(dev) short dev
+ #define major(dev) gnu_dev_major (dev)
+ #define minor(dev) gnu_dev_minor (dev)
+ #endif
Index: gcc/testsuite/g++.dg/pph/x1globalref.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/x1globalref.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1globalref.cc	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ #include "x1globalref.h"
+ type x = 2;
+ type y = x;
+ type f() { return n+m+a[3]+x+y; }
Index: gcc/testsuite/g++.dg/pph/c1struct.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/c1struct.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1struct.cc	(revision 0)
***************
*** 0 ****
--- 1,3 ----
+ #include "c1struct.h"
+ thing var1;
+ thing var2 = { 3 };
Index: gcc/testsuite/g++.dg/pph/where.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/where.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/where.cc	(working copy)
***************
*** 1,21 ****
- namespace A {
- int x = 3;
- struct B;
- struct C {
-     B* b;
-     int method();
-     int another()
-     { return 1; }
- };
- int C::method()
- { return 1; }
- } // namespace A
- struct D : A::C {
-     int method();
-     int another()
-     { return 1; }
- };
- int D::method()
- { return 1; }
- int main()
- { }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/simple2.h
===================================================================
*** gcc/testsuite/g++.dg/pph/simple2.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/simple2.h	(working copy)
***************
*** 1,7 ****
- #ifndef SIMPLE2_H
- #define SIMPLE2_H
- 
- #define assert(x) yellow(x)
- extern void yellow(int);
- 
- #endif
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/x1struct0.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x1struct0.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1struct0.h	(revision 0)
***************
*** 0 ****
--- 1,7 ----
+ #ifndef X1STRUCT0_H
+ #define X1STRUCT0_H
+ typedef int type;
+ struct B {
+ };
+ typedef B thing;
+ #endif
Index: gcc/testsuite/g++.dg/pph/meth2.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/meth2.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/meth2.cc	(working copy)
***************
*** 1,6 ****
- class one {
- };
- typedef one type;
- class two {
-     type fld;
- };
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/x1struct2.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/x1struct2.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1struct2.cc	(revision 0)
***************
*** 0 ****
--- 1,8 ----
+ #include "x1struct2.h"
+ type D::method()
+ { static int x = 2;
+   return fld + mbr + gbl; }
+ type D::mbr = 4;
+ typedef D D2;
+ D2 var1;
+ D2 var2 = var1;
Index: gcc/testsuite/g++.dg/pph/mean.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/mean.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/mean.cc	(working copy)
***************
*** 1,163 ****
- #include <stdlib.h>	// { dg-error "fatal" "invalid hunk" { xfail *-*-* } }
- #include <stdio.h>
- #include <math.h>
- #include <string.h>
- 
- static unsigned long long MAX_ITEMS = 10000;
- 
- static int
- cmpdouble (const void *p1, const void *p2)
- {
-   double n1 = *((double *)p1);
-   double n2 = *((double *)p2);
- 
-   if (n1 < n2)
-     return -1;
-   else if (n1 > n2)
-     return 1;
-   else
-     return 0;
- }
- 
- 
- double
- compute_median (int n, double vec[])
- {
-   qsort (vec, n, sizeof (double), cmpdouble);
-   
-   if (n % 2 == 0)
-     return ((vec[n / 2] + vec[n / 2 - 1]) / 2.0);
-   else
-     return vec[n / 2];
- }
- 
- double
- compute_stddev (int n, double avg, double vec[])
- {
-   double sd, sum, s, x;
-   int i;
- 
-   for (x = 0.0, sum = 0.0, i = 0; i < n; i++)
-     {
-       double d;
- 
-       x = x + vec[i];
-       d = vec[i] - avg;
-       sum += d * d;
-     }
- 
-   s = sum / n;
-   sd = sqrt (s);
- 
-   return sd;
- }
- 
- 
- int
- main (int argc, char *argv[])
- {
-   double *vec;
-   double x, sum, product, inverse_sum, arithmetic, geometric, harmonic;
-   double min, max, median, variance, stddev;
-   int count;
-   int ret;
- 
-   sum = 0.0;
-   product = 1.0;
-   inverse_sum = 0.0;
-   count = 0;
-   min = 0.0;
-   max = 0.0;
- 
-   vec = (double *) malloc (MAX_ITEMS * sizeof (double));
- 
-   while (1)
-     {
-       ret = scanf ("%lg", &x);
-       if (ret == EOF)
- 	break;
- 
-       if (count == 0)
- 	min = max = x;
- 
-       if (x < min)
- 	min = x;
- 
-       if (x > max)
- 	max = x;
- 
-       sum += x;
-       product *= x;
-       inverse_sum += 1.0 / x;
-       vec[count] = x;
- 
-       count++;
-       if (count >= MAX_ITEMS)
- 	{
- 	  MAX_ITEMS *= 3;
- 	  vec = (double *) realloc (vec, MAX_ITEMS * sizeof (double));
- 	}
-     }
- 
-   int do_min = (strstr (argv[0], "min") != NULL);
-   int do_max = (strstr (argv[0], "max") != NULL);
-   int do_avg = (strstr (argv[0], "avg") != NULL);
-   int do_geo = (strstr (argv[0], "geoavg") != NULL);
-   int do_harmonic = (strstr (argv[0], "harmonic") != NULL);
-   int do_median = (strstr (argv[0], "median") != NULL);
-   int do_variance = (strstr (argv[0], "variance") != NULL);
-   int do_stdev = (strstr (argv[0], "stdev") != NULL);
-   int do_all = (argc > 1 && strcmp (argv[1], "-a") == 0);
- 
-   if (count > 0)
-     {
-       arithmetic = sum / count;
-       geometric = pow (product, (double) 1.0 / (double) count);
-       harmonic = count / inverse_sum;
-       median = compute_median (count, vec);
-       stddev = compute_stddev (count, arithmetic, vec);
-       variance = stddev * stddev;
- 
-       if (do_all)
- 	{
- 	  printf ("# of items read --> %d\n", count);
- 	  printf ("Min --------------> %lg\n", min);
- 	  printf ("Max --------------> %lg\n", max);
- 	  printf ("Arithmetic mean --> %lg\n", arithmetic);
- 	  printf ("Geometric mean ---> %lg\n", geometric);
- 	  printf ("Harmonic mean ----> %lg\n", harmonic);
- 	  printf ("Median -----------> %lg\n", median);
- 	  printf ("Variance ---------> %lg\n", variance);
- 	  printf ("Standard dev -----> %lg\n", stddev);
- 	}
-       else if (do_min)
- 	printf ("%lg\n", min);
-       else if (do_max)
- 	printf ("%lg\n", max);
-       else if (do_avg)
- 	printf ("%lg\n", arithmetic);
-       else if (do_geo)
- 	printf ("%lg\n", geometric);
-       else if (do_harmonic)
- 	printf ("%lg\n", harmonic);
-       else if (do_median)
- 	printf ("%lg\n", median);
-       else if (do_variance)
- 	printf ("%lg\n", variance);
-       else if (do_stdev)
- 	printf ("%lg\n", stddev);
-       else
- 	{
- 	  fprintf (stderr, "ERROR: Unknown value '%s' to compute\n", argv[0]);
- 	  return 1;
- 	}
-     }
-   else
-     {
-       fprintf (stderr, "ERROR: none of the input is positive\n");
-       return 1;
-     }
- 
-   return 0;
- }
- // { dg-error "excess errors" "" { xfail *-*-* } }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/x1functions.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x1functions.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1functions.h	(revision 0)
***************
*** 0 ****
--- 1,15 ----
+ #ifndef X1FUNCTIONS_H
+ #define X1FUNCTIONS_H
+ #include "c1functions.h"
+ inline int extern_inline(int i)         // lazy body
+ { return extern_then_body(i); }
+ struct type {
+     int mbr_decl_only(int);
+     int mbr_decl_then_def(int);
+     inline int mbr_inl_then_def(int);
+     int mbr_decl_inline(int i)          // lazy body
+     { return mbr_decl_only( i ); }
+     virtual int mbr_virtual_inline()    // lazy body, but circular dependence
+     { return mbr_decl_only( 1 ); }
+ };
+ #endif
Index: gcc/testsuite/g++.dg/pph/nontrivinit.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/nontrivinit.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/nontrivinit.cc	(working copy)
***************
*** 1,2 ****
- int y = 0;
- int x = y+1;
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/autometh.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/autometh.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/autometh.cc	(working copy)
***************
*** 1,11 ****
- class base {
-     virtual int method() {
-         return 0;
-     }
-     int field;
- };
- void function() {
-     base var1;
-     base var2( var1 );
-     var1 = var2;
- }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/tmplfunc.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/tmplfunc.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/tmplfunc.cc	(working copy)
***************
*** 1,17 ****
- typedef int type;
- type val = 3;
- 
- template< typename T >
- T identity(T arg)
- { return arg + val; }
- 
- template<>
- int identity< type >(type arg)
- { return arg + val; }
- 
- template
- short identity(short arg);
- 
- int main() {
-   return identity( 'a' );
- }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/builtin1.h
===================================================================
*** gcc/testsuite/g++.dg/pph/builtin1.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/builtin1.h	(working copy)
***************
*** 1,2 ****
- #define QUOTE(arg) #arg
- #define VALUE(arg) QUOTE(arg)
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/x1autometh.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/x1autometh.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1autometh.cc	(revision 0)
***************
*** 0 ****
--- 1,6 ----
+ #include "x1autometh.h"
+ void function() {
+     base var1;
+     base var2( var1 );
+     var1 = var2;
+ }
Index: gcc/testsuite/g++.dg/pph/x1tmplfunc.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/x1tmplfunc.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1tmplfunc.cc	(revision 0)
***************
*** 0 ****
--- 1,13 ----
+ #include "x1tmplfunc.h"
+ type val = 3;
+ 
+ template<>
+ int identity< type >(type arg)
+ { return arg + val; }
+ 
+ template
+ short identity(short arg);
+ 
+ int main() {
+   return identity( 'a' );
+ }
Index: gcc/testsuite/g++.dg/pph/d2dupguard.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/d2dupguard.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/d2dupguard.cc	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ #include "c2dupguard1.h"
+ #include "c2dupguard2.h"
+ // { dg-error "duplicate PPH guard header" "" { xfail *-*-* } }
+ int foo() { return x; }
Index: gcc/testsuite/g++.dg/pph/funcstatic.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/funcstatic.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/funcstatic.cc	(working copy)
***************
*** 1,3 ****
- int f() {
-     static int x = 3;
- }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/p1systypes.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/p1systypes.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/p1systypes.cc	(revision 0)
***************
*** 0 ****
--- 1,2 ----
+ #include <sys/types.h>
+ loff_t variable = 0;
Index: gcc/testsuite/g++.dg/pph/builtin.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/builtin.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/builtin.cc	(working copy)
***************
*** 1,3 ****
- #include "builtin1.h"
- #include "builtin2.h"
- #include "builtin3.h"
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/d1symnotinc.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/d1symnotinc.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/d1symnotinc.cc	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ // { dg-bogus "Cannot open PPH file for reading" "" { xfail *-*-* } }
+ #define NAME v
+ #define VALUE 1
+ #include "d1symnotinc.h"
+ // { dg-excess-errors "compilation terminated" { xfail *-*-* } }
Index: gcc/testsuite/g++.dg/pph/x2overload1.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x2overload1.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x2overload1.h	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ #ifndef X2OVERLOAD1_H
+ #define X2OVERLOAD1_H
+ int o(double x);
+ #endif
Index: gcc/testsuite/g++.dg/pph/hardlookup.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/hardlookup.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/hardlookup.cc	(working copy)
***************
*** 1,29 ****
- struct V { int a; static int b;};
- namespace N {
-    int V;
-    struct C { };
-    int operator + (int i, C c);
-    C O;
-    int I(int arg)
-    { return arg + V; }
-    struct V w;
-    int x = V::b;
- }
- 
- int V;
- struct D { };
- D P;
- int operator + (int i, D d);
- int I(int arg)
- { return arg + V; }
- 
- int F() {
-    return I(N::V + N::O);
- }
- 
- int G() {
-    return I(::V + P);
- }
- 
- struct V w;
- int x = V::b;
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/incmod.h
===================================================================
*** gcc/testsuite/g++.dg/pph/incmod.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/incmod.h	(working copy)
***************
*** 1 ****
- struct T NAME = { VALUE };
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/sys-types.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/sys-types.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/sys-types.cc	(working copy)
***************
*** 1,2 ****
- #include <sys/types.h> 	// { dg-error "fatal" "invalid hunk" { xfail *-*-* } }
- // { dg-error "excess errors" "" { xfail *-*-* } }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/incsame.h
===================================================================
*** gcc/testsuite/g++.dg/pph/incsame.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/incsame.h	(working copy)
***************
*** 1 ****
- = { 1 };
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/c1altinc2.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1altinc2.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1altinc2.h	(revision 0)
***************
*** 0 ****
--- 1,12 ----
+ #ifndef C1ALTINC2
+ #define C1ALTINC2
+ extern void foo (void);
+ #define X	1
+ #if defined X
+ #include "c1altinc1.h"
+ extern int var1;
+ extern int var2;
+ #else
+ #include "c1altinc1.h"
+ #endif
+ #endif
Index: gcc/testsuite/g++.dg/pph/x1variables.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x1variables.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1variables.h	(revision 0)
***************
*** 0 ****
--- 1,11 ----
+ #ifndef X1VARIABLES_H
+ #define X1VARIABLES_H
+ #include "c1variables.h"
+ struct D {
+     static int mbr_init_plain;
+     static int mbr_uninit_plain;
+     static const int mbr_init_const;
+     static const int mbr_uninit_const;
+     static const int mbr_manifest = 3;
+ };
+ #endif
Index: gcc/testsuite/g++.dg/pph/classshort.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/classshort.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/classshort.cc	(working copy)
***************
*** 1,19 ****
- typedef int type;
- type gbl = 1;
- struct B {
-     type fld;
- };
- struct D : B {
-     type method();
-     type another()
-     { return fld + mbr + gbl; }
-     type fld;
-     static type mbr;
- };
- type D::method()
- { static int x = 2;
-   return fld + mbr + gbl; }
- type D::mbr = 4;
- typedef D D2;
- D2 var1;
- D2 var2 = var1;
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/x1template.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x1template.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1template.h	(revision 0)
***************
*** 0 ****
--- 1,22 ----
+ #ifndef X1TEMPLATE_H
+ #define X1TEMPLATE_H
+ namespace A {
+ extern int x;
+ struct B;
+ template< typename T >
+ struct C {
+     T* b;
+     int method();
+     int another()
+     { return *b; }
+ };
+ template< typename T >
+ int C< T >::method()
+ { return x; }
+ } // namespace A
+ struct D : A::C< int > {
+     int method();
+     int another()
+     { return *b; }
+ };
+ #endif
Index: gcc/testsuite/g++.dg/pph/x1special.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/x1special.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1special.cc	(revision 0)
***************
*** 0 ****
--- 1,12 ----
+ #include "x1special.h"
+ B b(1);
+ 
+ int H() {
+     F(b);
+     B a(3.2);
+     B c = b;
+     B d(b);
+     c = b;
+     d = 4;
+     G(d);
+ }
Index: gcc/testsuite/g++.dg/pph/x2nontrivinit.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/x2nontrivinit.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/x2nontrivinit.cc	(revision 0)
***************
*** 0 ****
--- 1 ----
+ #include "x2nontrivinit.h"
Index: gcc/testsuite/g++.dg/pph/pph.exp
===================================================================
*** gcc/testsuite/g++.dg/pph/pph.exp	(revision 170223)
--- gcc/testsuite/g++.dg/pph/pph.exp	(working copy)
***************
*** 17,22 ****
--- 17,23 ----
  # GCC testsuite for preparsed header interaction.
  
  # Contributed by Diego Novillo <dnovillo@google.com>
+ # Adapted to new command-driven scheme by Lawrence Crowl <crowl@google.com>
  
  # Load support procs.
  load_lib "g++-dg.exp"
*************** load_lib dg-pph.exp
*** 25,38 ****
  # Initialize `dg'.
  dg-init
  
! set old_dg_do_what_default "${dg-do-what-default}"
  
! # Main loop.
! foreach test [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] {
!     dg-pph $subdir $test [list "-fpth" ] ".pth"
! }
  
! set dg-do-what-default "$old_dg_do_what_default"
  
  # All done.
  dg-finish
--- 26,70 ----
  # Initialize `dg'.
  dg-init
  
! # FIXME set scenarios [list "" "-g" "-O"]
! set scenarios [list "" ]
  
! set hdr_tests [lsort [glob -nocomplain $srcdir/$subdir/\[cdx\]*.h]]
! set neg_tests [lsort [glob -nocomplain $srcdir/$subdir/\[dy\]*.cc]]
! set pos_tests [lsort [glob -nocomplain $srcdir/$subdir/\[cpx\]*.cc]]
! set mapflag -fpph-map=$srcdir/$subdir/pph.map
! 
! foreach scenario $scenarios {
! 
!     set old_dg_do_what_default "${dg-do-what-default}"
! 
!     #system headers
!     dg-pph-hdr $subdir /usr/include/math.h $scenario "" ".pph"
!     dg-pph-hdr $subdir /usr/include/stdio.h $scenario "" ".pph"
!     dg-pph-hdr $subdir /usr/include/stdlib.h $scenario "" ".pph"
!     dg-pph-hdr $subdir /usr/include/string.h $scenario "" ".pph"
!     dg-pph-hdr $subdir /usr/include/sys/types.h $scenario "" ".pph"
! 
!     # Header file loop.
!     # Each pph header must include only pph headers
!     # that are lexicographically earlier than itself.
!     foreach test $hdr_tests {
!         dg-pph-hdr $subdir $test $scenario $mapflag ".pph"
!     }
! 
!     # Source file loop for negative tests.
!     foreach test $neg_tests {
!         dg-pph-neg $subdir $test $scenario $mapflag ".pph"
!     }
! 
!     # Source file loop for positive tests.
!     foreach test $pos_tests {
!         dg-pph-pos $subdir $test $scenario $mapflag ".pph"
!     }
! 
!     set dg-do-what-default "$old_dg_do_what_default"
  
! }
  
  # All done.
  dg-finish
Index: gcc/testsuite/g++.dg/pph/c1simple1.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1simple1.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1simple1.h	(revision 0)
***************
*** 0 ****
--- 1,7 ----
+ #ifndef C1SIMPLE1_H
+ #define C1SIMPLE1_H
+ 
+ #define assert(x) yellow(x)
+ extern void yellow(int);
+ 
+ #endif
Index: gcc/testsuite/g++.dg/pph/c1chained1.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1chained1.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1chained1.h	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ #ifndef C1CHAINED1_H
+ #define C1CHAINED1_H
+ #define ONE 1
+ #endif
Index: gcc/testsuite/g++.dg/pph/tmplclass.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/tmplclass.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/tmplclass.cc	(working copy)
***************
*** 1,29 ****
- template< typename T >
- struct wrapper {
-   T value;
-   static T cache;
- };
- 
- template< typename T >
- T wrapper<T>::cache = 3;
- 
- template<>
- struct wrapper<char> {
-   int value;
-   static int cache;
- };
- 
- int wrapper<char>::cache = 2;
- 
- template
- struct wrapper<short>;
- 
- template
- long wrapper<long>::cache;
- 
- int main() {
-   wrapper<char> vc;
-   wrapper<short> vs;
-   wrapper<int> vi;
-   return 0;
- }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/trivial.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/trivial.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/trivial.cc	(working copy)
***************
*** 1,3 ****
- int main()
- {
- }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/template.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/template.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/template.cc	(working copy)
***************
*** 1,24 ****
- namespace A {
- int x = 3;
- struct B;
- template< typename T >
- struct C {
-     T* b;
-     int method();
-     int another()
-     { return *b; }
- };
- template< typename T >
- int C< T >::method()
- { return x; }
- } // namespace A
- int y = 4;
- struct D : A::C< int > {
-     int method();
-     int another()
-     { return *b; }
- };
- int D::method()
- { return y; }
- int main()
- { }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/c1simple.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/c1simple.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1simple.cc	(revision 0)
***************
*** 0 ****
--- 1,6 ----
+ /* comment */
+ #include "c1simple2.h"
+ int main()
+ {
+ 	return foo();
+ }
Index: gcc/testsuite/g++.dg/pph/x1funcstatic.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x1funcstatic.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1funcstatic.h	(revision 0)
***************
*** 0 ****
--- 1,7 ----
+ #ifndef X1FUNCSTATIC_H
+ #define X1FUNCSTATIC_H
+ static int f() {
+     static int x = 3;
+     return x++;
+ }
+ #endif
Index: gcc/testsuite/g++.dg/pph/chained1.h
===================================================================
*** gcc/testsuite/g++.dg/pph/chained1.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/chained1.h	(working copy)
***************
*** 1 ****
- #define ONE 1
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/c2builtin1.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c2builtin1.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c2builtin1.h	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ #ifndef C2BUILTIN1_H
+ #define C2BUILTIN1_H
+ #define QUOTE(arg) #arg
+ #define VALUE(arg) QUOTE(arg)
+ #endif
Index: gcc/testsuite/g++.dg/pph/a2builtin4.h
===================================================================
*** gcc/testsuite/g++.dg/pph/a2builtin4.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/a2builtin4.h	(revision 0)
***************
*** 0 ****
--- 1,2 ----
+ #define QUOTE(arg) #arg
+ #define VALUE(arg) QUOTE(arg)
Index: gcc/testsuite/g++.dg/pph/pph.map
===================================================================
*** gcc/testsuite/g++.dg/pph/pph.map	(revision 0)
--- gcc/testsuite/g++.dg/pph/pph.map	(revision 0)
***************
*** 0 ****
--- 1,48 ----
+ c1altinc1.h	c1altinc1.pph
+ c1altinc2.h	c1altinc2.pph
+ c1chained1.h	c1chained1.pph
+ c1chained2.h	c1chained2.pph
+ c1empty.h	c1empty.pph
+ c1field.h	c1field.pph
+ c1funcmac.h	c1funcmac.pph
+ c1functions.h	c1functions.pph
+ c1guarded1.h	c1guarded1.pph
+ c1guarded2.h	c1guarded2.pph
+ c1guarded3.h	c1guarded3.pph
+ c1multinc1.h	c1multinc1.pph
+ c1multinc2.h	c1multinc2.pph
+ c1simple1.h	c1simple1.pph
+ c1simple2.h	c1simple2.pph
+ c1struct.h	c1struct.pph
+ c1typerefs.h	c1typerefs.pph
+ c1variables.h	c1variables.pph
+ c2builtin1.h	c2builtin1.pph
+ c2builtin2.h	c2builtin2.pph
+ c2builtin3.h	c2builtin3.pph
+ c2dupguard1.h	c2dupguard1.pph
+ c2dupguard2.h	c2dupguard2.pph
+ c2paste.h	c2paste.pph
+ d1symnotinc.h	d1symnotinc.pph
+ math.h	math.pph
+ stdio.h	stdio.pph
+ stdlib.h	stdlib.pph
+ string.h	string.pph
+ sys/types.h	types.pph
+ x1autometh.h	x1autometh.pph
+ x1funcstatic.h	x1funcstatic.pph
+ x1functions.h	x1functions.pph
+ x1globalref.h	x1globalref.pph
+ x1hardlookup.h	x1hardlookup.pph
+ x1special.h	x1special.pph
+ x1struct0.h	x1struct0.pph
+ x1struct1.h	x1struct1.pph
+ x1struct2.h	x1struct2.pph
+ x1template.h	x1template.pph
+ x1tmplclass.h	x1tmplclass.pph
+ x1tmplfunc.h	x1tmplfunc.pph
+ x1typerefs.h	x1typerefs.pph
+ x1variables.h	x1variables.pph
+ x2nontrivinit.h	x2nontrivinit.pph
+ y2overload1.h	y2overload1.pph
+ y2overload2.h	y2overload2.pph
+ y2overload3.h	y2overload3.pph
Index: gcc/testsuite/g++.dg/pph/x1struct1.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x1struct1.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1struct1.h	(revision 0)
***************
*** 0 ****
--- 1,11 ----
+ #ifndef X1STRUCT1_H
+ #define X1STRUCT1_H
+ #include "x1struct0.h"
+ struct D : public thing {
+     type method();
+     type another()
+     { return fld + mbr; }
+     type fld;
+     static type mbr;
+ };
+ #endif
Index: gcc/testsuite/g++.dg/pph/special.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/special.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/special.cc	(working copy)
***************
*** 1,30 ****
- struct B {
-     B( int );
-     B( double );
-     B( const B& );
-     B& operator=( const B& );
-     B& operator=( int );
-     operator double();
-     ~B();
- };
- 
- struct D {
-     D( const B& );
- };
- 
- int F( D );
- int G( double );
- 
- B b(1);
- //B q("hhh");
- 
- int H() {
-     F(b);
-     B a(3.2);
-     B c = b;
-     B d(b);
-     c = b;
-     d = 4;
-     //G(double(""));
-     G(d);
- }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/p1stdlib.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/p1stdlib.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/p1stdlib.cc	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ #include <stdlib.h>
+ int f(const char* s)
+ {
+     return atoi(s);
+ }
Index: gcc/testsuite/g++.dg/pph/c2builtin5.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c2builtin5.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c2builtin5.h	(revision 0)
***************
*** 0 ****
--- 1,9 ----
+ #ifndef C2BUILTIN5_H
+ #define C2BUILTIN5_H
+ #include "a2builtin4.h"
+ const char *file = VALUE(__FILE__);
+ const char *line = VALUE(__LINE__);
+ const char *vers = VALUE(__cplusplus);
+ const char *optm = VALUE(__OPTIMIZE__);
+ const char *func() { return __func__; }
+ #endif
Index: gcc/testsuite/g++.dg/pph/c1guarded1.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1guarded1.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1guarded1.h	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ #ifndef C1GUARDED1_H
+ #define C1GUARDED1_H
+ typedef int type;
+ #endif
Index: gcc/testsuite/g++.dg/pph/x1template.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/x1template.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1template.cc	(revision 0)
***************
*** 0 ****
--- 1,9 ----
+ #include "x1template.h"
+ namespace A {
+ int x = 3;
+ } // namespace A
+ int y = 4;
+ int D::method()
+ { return y; }
+ int main()
+ { }
Index: gcc/testsuite/g++.dg/pph/builtin2.h
===================================================================
*** gcc/testsuite/g++.dg/pph/builtin2.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/builtin2.h	(working copy)
***************
*** 1,7 ****
- const char *date = VALUE(__DATE__);
- const char *time = VALUE(__TIME__);
- const char *file = VALUE(__FILE__);
- const char *line = VALUE(__LINE__);
- const char *vers = VALUE(__cplusplus);
- const char *optm = VALUE(__OPTIMIZE__);
- const char *func() { return __func__; }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/chained.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/chained.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/chained.cc	(working copy)
***************
*** 1,3 ****
- #include "chained1.h"
- #include "chained2.h"
- int x = TWO;
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/usearray.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/usearray.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/usearray.cc	(working copy)
***************
*** 1,8 ****
- #include "usearray.h"
- const int x = 3;
- const int y = 10;
- float array[x + y];
- float foo (int i)
- {
-   return array[i * 3];
- }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/usearray.h
===================================================================
*** gcc/testsuite/g++.dg/pph/usearray.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/usearray.h	(working copy)
***************
*** 1 ****
- float foo(int);
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/meth.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/meth.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/meth.cc	(working copy)
***************
*** 1,4 ****
- typedef int type;
- class base {
-     type fld;
- };
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/guarded1.h
===================================================================
*** gcc/testsuite/g++.dg/pph/guarded1.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/guarded1.h	(working copy)
***************
*** 1,6 ****
- #ifndef GUARDED1_H
- #define GUARDED1_H
- 
- typedef int type;
- 
- #endif
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/c1guarded.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/c1guarded.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1guarded.cc	(revision 0)
***************
*** 0 ****
--- 1,2 ----
+ #include "c1guarded2.h"
+ #include "c1guarded3.h"
Index: gcc/testsuite/g++.dg/pph/c2paste.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/c2paste.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/c2paste.cc	(revision 0)
***************
*** 0 ****
--- 1,6 ----
+ #include "c2paste.h"
+ void foo_30_(int);
+ void bar(void)
+ {
+   M(30);
+ }
Index: gcc/testsuite/g++.dg/pph/d2null.h
===================================================================
*** gcc/testsuite/g++.dg/pph/d2null.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/d2null.h	(revision 0)
***************
*** 0 ****
--- 1 ----
+ // { dg-error "header lacks guard for PPH" "" { xfail *-*-* } }
Index: gcc/testsuite/g++.dg/pph/x1tmplfunc.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x1tmplfunc.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1tmplfunc.h	(revision 0)
***************
*** 0 ****
--- 1,9 ----
+ #ifndef X1TMPLFUNC_H
+ #define X1TMPLFUNC_H
+ typedef int type;
+ extern type val;
+ 
+ template< typename T >
+ T identity(T arg)
+ { return arg + val; }
+ #endif
Index: gcc/testsuite/g++.dg/pph/c1field.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/c1field.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1field.cc	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ #include "c1field.h"
+ struct client {
+     program field;
+ };
+ client variable;
Index: gcc/testsuite/g++.dg/pph/x2overload2.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x2overload2.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x2overload2.h	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ #ifndef X2OVERLOAD2_H
+ #define X2OVERLOAD2_H
+ int o(float x);
+ #endif
Index: gcc/testsuite/g++.dg/pph/c1struct.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1struct.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1struct.h	(revision 0)
***************
*** 0 ****
--- 1,9 ----
+ #ifndef C1STRUCT_H
+ #define C1STRUCT_H
+ typedef int type;
+ type gbl = 1;
+ struct B {
+     type fld;
+ };
+ typedef B thing;
+ #endif
Index: gcc/testsuite/g++.dg/pph/guarded.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/guarded.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/guarded.cc	(working copy)
***************
*** 1,2 ****
- #include "guarded2.h"
- #include "guarded3.h"
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/x1tmplclass.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/x1tmplclass.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1tmplclass.cc	(revision 0)
***************
*** 0 ****
--- 1,15 ----
+ #include "x1tmplclass.h"
+ int wrapper<char>::cache = 2;
+ 
+ template
+ struct wrapper<short>;
+ 
+ template
+ long wrapper<long>::cache;
+ 
+ int main() {
+   wrapper<char> vc;
+   wrapper<short> vs;
+   wrapper<int> vi;
+   return 0;
+ }
Index: gcc/testsuite/g++.dg/pph/c2builtin1.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/c2builtin1.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/c2builtin1.cc	(revision 0)
***************
*** 0 ****
--- 1,3 ----
+ #include "c2builtin1.h"
+ #include "c2builtin2.h"
+ #include "c2builtin3.h"
Index: gcc/testsuite/g++.dg/pph/paste.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/paste.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/paste.cc	(working copy)
***************
*** 1,10 ****
- #define major	"beef"
- #define M(major)	foo##_##major##_(major)
- 
- void foo_30_(int);
- void bar(void);
- 
- void bar(void)
- {
-   M(30);
- }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/x1funcstatic.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/x1funcstatic.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1funcstatic.cc	(revision 0)
***************
*** 0 ****
--- 1,2 ----
+ #include "x1funcstatic.h"
+ int a = f();
Index: gcc/testsuite/g++.dg/pph/x1tmplclass.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x1tmplclass.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1tmplclass.h	(revision 0)
***************
*** 0 ****
--- 1,17 ----
+ #ifndef X1TMPLCLASS_H
+ #define X1TMPLCLASS_H
+ template< typename T >
+ struct wrapper {
+   T value;
+   static T cache;
+ };
+ 
+ template< typename T >
+ T wrapper<T>::cache = 3;
+ 
+ template<>
+ struct wrapper<char> {
+   int value;
+   static int cache;
+ };
+ #endif
Index: gcc/testsuite/g++.dg/pph/x1hardlookup.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/x1hardlookup.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1hardlookup.cc	(revision 0)
***************
*** 0 ****
--- 1,15 ----
+ #include "x1hardlookup.h"
+ D P;
+ int I(int arg)
+ { return arg + V; }
+ 
+ int F() {
+    return I(N::V + N::O);
+ }
+ 
+ int G() {
+    return I(::V + P);
+ }
+ 
+ struct V w;
+ int x = V::b;
Index: gcc/testsuite/g++.dg/pph/c1empty.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/c1empty.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1empty.cc	(revision 0)
***************
*** 0 ****
--- 1 ----
+ #include "c1empty.h"
Index: gcc/testsuite/g++.dg/pph/field.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/field.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/field.cc	(working copy)
***************
*** 1,7 ****
- typedef int language;
- struct program {
-     language field;
- };
- struct client {
-     program field;
- };
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/variable.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/variable.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/variable.cc	(working copy)
***************
*** 1,2 ****
- int one;
- int two;
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/inif.h
===================================================================
*** gcc/testsuite/g++.dg/pph/inif.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/inif.h	(working copy)
***************
*** 1 ****
- extern float f1;
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/x1special.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x1special.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1special.h	(revision 0)
***************
*** 0 ****
--- 1,21 ----
+ #ifndef X1SPECIAL_H
+ #define X1SPECIAL_H
+ 
+ struct B {
+     B( int );
+     B( double );
+     B( const B& );
+     B& operator=( const B& );
+     B& operator=( int );
+     operator double();
+     ~B();
+ };
+ 
+ struct D {
+     D( const B& );
+ };
+ 
+ int F( D );
+ int G( double );
+ 
+ #endif
Index: gcc/testsuite/g++.dg/pph/empty.cc
===================================================================
Index: gcc/testsuite/g++.dg/pph/c1functions.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1functions.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1functions.h	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ #ifndef C1FUNCTIONS_H
+ #define C1FUNCTIONS_H
+ extern int extern_only(int);            //
+ extern int extern_then_body(int);       //
+ #endif
Index: gcc/testsuite/g++.dg/pph/staticmbrvar.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/staticmbrvar.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/staticmbrvar.cc	(working copy)
***************
*** 1,5 ****
- struct D {
-     int method() { return mbr; }
-     static int mbr;
- };
- int D::mbr = 4;
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/typerefs.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/typerefs.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/typerefs.cc	(working copy)
***************
*** 1,18 ****
- struct base {
-     int field;
- };
- base function();
- int base_from_var() {
-     base variable;
- }
- int base_from_func() {
-     function();
- }
- struct derived : base {
-     int method();
- };
- int derived::method() {
-     return field;
- }
- struct vderived : virtual base {
- };
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/c1simple2.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1simple2.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1simple2.h	(revision 0)
***************
*** 0 ****
--- 1,11 ----
+ #ifndef C1SIMPLE2_H
+ #define C1SIMPLE2_H
+ 
+ #include "c1simple1.h"
+ 
+ inline int foo()
+ {
+   assert(1);
+ }
+ 
+ #endif
Index: gcc/testsuite/g++.dg/pph/c1chained2.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1chained2.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1chained2.h	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ #ifndef C1CHAINED2_H
+ #define C1CHAINED2_H
+ #define TWO ONE
+ #endif
Index: gcc/testsuite/g++.dg/pph/system-include.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/system-include.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/system-include.cc	(working copy)
***************
*** 1,3 ****
- #include <stdlib.h>	// { dg-error "fatal" "invalid hunk" { xfail *-*-* } }
- size_t X;
- // { dg-error "excess errors" "" { xfail *-*-* } }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/d1symnotinc.h
===================================================================
*** gcc/testsuite/g++.dg/pph/d1symnotinc.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/d1symnotinc.h	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ #ifndef D1SDYMNOTINC_H
+ #define D1SDYMNOTINC_H
+ struct T { int f; };
+ struct T NAME = { VALUE }; // { dg-error "was not declared in this scope" }
+ #endif
Index: gcc/testsuite/g++.dg/pph/x1typerefs.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/x1typerefs.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1typerefs.cc	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ #include "x1typerefs.h"
+ int derived::method() {
+     return field;
+ }
+ vderived variable;
Index: gcc/testsuite/g++.dg/pph/chained2.h
===================================================================
*** gcc/testsuite/g++.dg/pph/chained2.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/chained2.h	(working copy)
***************
*** 1 ****
- #define TWO ONE
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/c2builtin2.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c2builtin2.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c2builtin2.h	(revision 0)
***************
*** 0 ****
--- 1,9 ----
+ #ifndef C2BUILTIN2_H
+ #define C2BUILTIN2_H
+ #include "c2builtin1.h"
+ const char *file = VALUE(__FILE__);
+ const char *line = VALUE(__LINE__);
+ const char *vers = VALUE(__cplusplus);
+ const char *optm = VALUE(__OPTIMIZE__);
+ const char *func() { return __func__; }
+ #endif
Index: gcc/testsuite/g++.dg/pph/p1mean.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/p1mean.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/p1mean.cc	(revision 0)
***************
*** 0 ****
--- 1,162 ----
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <math.h>
+ #include <string.h>
+ 
+ static unsigned long long MAX_ITEMS = 10000;
+ 
+ static int
+ cmpdouble (const void *p1, const void *p2)
+ {
+   double n1 = *((double *)p1);
+   double n2 = *((double *)p2);
+ 
+   if (n1 < n2)
+     return -1;
+   else if (n1 > n2)
+     return 1;
+   else
+     return 0;
+ }
+ 
+ 
+ double
+ compute_median (int n, double vec[])
+ {
+   qsort (vec, n, sizeof (double), cmpdouble);
+   
+   if (n % 2 == 0)
+     return ((vec[n / 2] + vec[n / 2 - 1]) / 2.0);
+   else
+     return vec[n / 2];
+ }
+ 
+ double
+ compute_stddev (int n, double avg, double vec[])
+ {
+   double sd, sum, s, x;
+   int i;
+ 
+   for (x = 0.0, sum = 0.0, i = 0; i < n; i++)
+     {
+       double d;
+ 
+       x = x + vec[i];
+       d = vec[i] - avg;
+       sum += d * d;
+     }
+ 
+   s = sum / n;
+   sd = sqrt (s);
+ 
+   return sd;
+ }
+ 
+ 
+ int
+ main (int argc, char *argv[])
+ {
+   double *vec;
+   double x, sum, product, inverse_sum, arithmetic, geometric, harmonic;
+   double min, max, median, variance, stddev;
+   int count;
+   int ret;
+ 
+   sum = 0.0;
+   product = 1.0;
+   inverse_sum = 0.0;
+   count = 0;
+   min = 0.0;
+   max = 0.0;
+ 
+   vec = (double *) malloc (MAX_ITEMS * sizeof (double));
+ 
+   while (1)
+     {
+       ret = scanf ("%lg", &x);
+       if (ret == EOF)
+ 	break;
+ 
+       if (count == 0)
+ 	min = max = x;
+ 
+       if (x < min)
+ 	min = x;
+ 
+       if (x > max)
+ 	max = x;
+ 
+       sum += x;
+       product *= x;
+       inverse_sum += 1.0 / x;
+       vec[count] = x;
+ 
+       count++;
+       if (count >= MAX_ITEMS)
+ 	{
+ 	  MAX_ITEMS *= 3;
+ 	  vec = (double *) realloc (vec, MAX_ITEMS * sizeof (double));
+ 	}
+     }
+ 
+   int do_min = (strstr (argv[0], "min") != NULL);
+   int do_max = (strstr (argv[0], "max") != NULL);
+   int do_avg = (strstr (argv[0], "avg") != NULL);
+   int do_geo = (strstr (argv[0], "geoavg") != NULL);
+   int do_harmonic = (strstr (argv[0], "harmonic") != NULL);
+   int do_median = (strstr (argv[0], "median") != NULL);
+   int do_variance = (strstr (argv[0], "variance") != NULL);
+   int do_stdev = (strstr (argv[0], "stdev") != NULL);
+   int do_all = (argc > 1 && strcmp (argv[1], "-a") == 0);
+ 
+   if (count > 0)
+     {
+       arithmetic = sum / count;
+       geometric = pow (product, (double) 1.0 / (double) count);
+       harmonic = count / inverse_sum;
+       median = compute_median (count, vec);
+       stddev = compute_stddev (count, arithmetic, vec);
+       variance = stddev * stddev;
+ 
+       if (do_all)
+ 	{
+ 	  printf ("# of items read --> %d\n", count);
+ 	  printf ("Min --------------> %lg\n", min);
+ 	  printf ("Max --------------> %lg\n", max);
+ 	  printf ("Arithmetic mean --> %lg\n", arithmetic);
+ 	  printf ("Geometric mean ---> %lg\n", geometric);
+ 	  printf ("Harmonic mean ----> %lg\n", harmonic);
+ 	  printf ("Median -----------> %lg\n", median);
+ 	  printf ("Variance ---------> %lg\n", variance);
+ 	  printf ("Standard dev -----> %lg\n", stddev);
+ 	}
+       else if (do_min)
+ 	printf ("%lg\n", min);
+       else if (do_max)
+ 	printf ("%lg\n", max);
+       else if (do_avg)
+ 	printf ("%lg\n", arithmetic);
+       else if (do_geo)
+ 	printf ("%lg\n", geometric);
+       else if (do_harmonic)
+ 	printf ("%lg\n", harmonic);
+       else if (do_median)
+ 	printf ("%lg\n", median);
+       else if (do_variance)
+ 	printf ("%lg\n", variance);
+       else if (do_stdev)
+ 	printf ("%lg\n", stddev);
+       else
+ 	{
+ 	  fprintf (stderr, "ERROR: Unknown value '%s' to compute\n", argv[0]);
+ 	  return 1;
+ 	}
+     }
+   else
+     {
+       fprintf (stderr, "ERROR: none of the input is positive\n");
+       return 1;
+     }
+ 
+   return 0;
+ }
Index: gcc/testsuite/g++.dg/pph/x1struct2.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x1struct2.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1struct2.h	(revision 0)
***************
*** 0 ****
--- 1,11 ----
+ #ifndef X1STRUCT_H
+ #define X1STRUCT_H
+ #include "c1struct.h"
+ struct D : thing {
+     type method();
+     type another()
+     { return fld + mbr + gbl; }
+     type fld;
+     static type mbr;
+ };
+ #endif
Index: gcc/testsuite/g++.dg/pph/c1multinc1.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1multinc1.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1multinc1.h	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ #ifndef C1MULTINC1_H
+ #define C1MULTINC1_H
+ extern float f1;
+ #endif
Index: gcc/testsuite/g++.dg/pph/c2dupguard1.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c2dupguard1.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c2dupguard1.h	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ #ifndef C2DUPGUARD_H
+ #define C2DUPGUARD_H
+ extern int x;
+ #endif
Index: gcc/testsuite/g++.dg/pph/c2builtin6.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c2builtin6.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c2builtin6.h	(revision 0)
***************
*** 0 ****
--- 1,6 ----
+ #ifndef C2BUILTIN6_H
+ #define C2BUILTIN6_H
+ #include "a2builtin4.h"
+ const char *refile = VALUE(__FILE__);
+ const char *reline = VALUE(__LINE__);
+ #endif
Index: gcc/testsuite/g++.dg/pph/c1guarded2.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1guarded2.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1guarded2.h	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ #ifndef C1GUARDED2_H
+ #define C1GUARDED2_H
+ #include "c1guarded1.h"
+ type variable2;
+ #endif
Index: gcc/testsuite/g++.dg/pph/c1empty.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1empty.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1empty.h	(revision 0)
***************
*** 0 ****
--- 1,3 ----
+ #ifndef C1EMPTY_H
+ #define C1EMPTY_H
+ #endif
Index: gcc/testsuite/g++.dg/pph/builtin3.h
===================================================================
*** gcc/testsuite/g++.dg/pph/builtin3.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/builtin3.h	(working copy)
***************
*** 1,2 ****
- const char *refile = VALUE(__FILE__);
- const char *reline = VALUE(__LINE__);
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/c1functions.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/c1functions.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1functions.cc	(revision 0)
***************
*** 0 ****
--- 1,6 ----
+ #include "c1functions.h"
+ int extern_then_body(int i)             // need body, merge head to body
+ { return extern_only( i ); }
+ static int fwdref_static(int);
+ int fwdref_static(int i)
+ { return extern_then_body( i ); }       // need body, merge head to body
Index: gcc/testsuite/g++.dg/pph/c1variables.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1variables.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1variables.h	(revision 0)
***************
*** 0 ****
--- 1,7 ----
+ #ifndef C1VARIABLES_H
+ #define C1VARIABLES_H
+ extern int gbl_init_extern;
+ extern int gbl_uninit_extern;
+ int gbl_tentative;
+ extern const int gbl_extern_const;
+ #endif
Index: gcc/testsuite/g++.dg/pph/guarded2.h
===================================================================
*** gcc/testsuite/g++.dg/pph/guarded2.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/guarded2.h	(working copy)
***************
*** 1,8 ****
- #ifndef GUARDED2_H
- #define GUARDED2_H
- 
- #include "guarded1.h"
- 
- type variable2;
- 
- #endif
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/c1multinc.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/c1multinc.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1multinc.cc	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ #include "c1multinc2.h"
+ void foo (void)
+ {
+   int x = var1 + var2 - (int) f1;
+ }
Index: gcc/testsuite/g++.dg/pph/c1funcmac.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/c1funcmac.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1funcmac.cc	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ #include "c1funcmac.h"
+ #define outer(major, minor) inner(major, minor)
+ void outer(long one, short two) { }
+ major(three);
+ minor(four);
Index: gcc/testsuite/g++.dg/pph/x1autometh.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x1autometh.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1autometh.h	(revision 0)
***************
*** 0 ****
--- 1,9 ----
+ #ifndef X1AUTOMETH_H
+ #define X1AUTOMETH_H
+ class base {
+     virtual int method() {
+         return 0;
+     }
+     int field;
+ };
+ #endif
Index: gcc/testsuite/g++.dg/pph/c2paste.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c2paste.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c2paste.h	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ #ifndef C2PASTE_H
+ #define C2PASTE_H
+ #define major	"beef"
+ #define M(major)	foo##_##major##_(major)
+ #endif
Index: gcc/testsuite/g++.dg/pph/x1globalref.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x1globalref.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1globalref.h	(revision 0)
***************
*** 0 ****
--- 1,7 ----
+ #ifndef X1GLOBALREF_H
+ #define X1GLOBALREF_H
+ typedef int type;
+ const type n = 3;
+ const type m = 4;
+ type a[n+m];
+ #endif
Index: gcc/testsuite/g++.dg/pph/functions.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/functions.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/functions.cc	(working copy)
***************
*** 1,22 ****
- extern int extern_only(int);		//
- extern int extern_then_body(int);	//
- inline int extern_inline(int i)		// lazy body
- { return extern_then_body(i); }
- int extern_then_body(int i)		// need body, merge head to body
- { return extern_only( i ); }
- static int fwdref_static(int);
- int fwdref_static(int i)
- { return extern_then_body( i ); }	// need body, merge head to body
- struct type {
-     int mbr_decl_only(int);
-     int mbr_decl_then_def(int);
-     inline int mbr_inl_then_def(int);
-     int mbr_decl_inline(int i)		// lazy body
-     { return mbr_decl_only( i ); }
-     virtual int mbr_virtual_inline()	// lazy body, but circular dependence
-     { return mbr_decl_only( 1 ); }
- };
- int type::mbr_decl_then_def(int i)	// need body
- { return mbr_decl_inline( i ); }
- int type::mbr_inl_then_def(int i)	// lazy body
- { return mbr_decl_then_def( i ); }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/x2overload3.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x2overload3.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x2overload3.h	(revision 0)
***************
*** 0 ****
--- 1,9 ----
+ #ifndef X2OVERLOAD3_H
+ #define X2OVERLOAD3_H
+ #include "x2overload1.h"
+ inline int f()
+ {
+     float x = 2.3f;
+     return o(x);
+ }
+ #endif
Index: gcc/testsuite/g++.dg/pph/cflow.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/cflow.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/cflow.cc	(working copy)
***************
*** 1,6 ****
- #include "cflow.h"
- 
- void foo (void)
- {
-   int x = var1 + var2 - (int) f1;
- }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/x1typerefs.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x1typerefs.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1typerefs.h	(revision 0)
***************
*** 0 ****
--- 1,9 ----
+ #ifndef X1TYPEREFS_H
+ #define X1TYPEREFS_H
+ #include "c1typerefs.h"
+ struct derived : base {
+     int method();
+ };
+ struct vderived : virtual base {
+ };
+ #endif
Index: gcc/testsuite/g++.dg/pph/x1struct1.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/x1struct1.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1struct1.cc	(revision 0)
***************
*** 0 ****
--- 1,8 ----
+ #include "x1struct1.h"
+ type D::method()
+ { static int x = 2;
+   return fld + mbr; }
+ type D::mbr = 4;
+ typedef D D2;
+ D2 var1;
+ D2 var2 = var1;
Index: gcc/testsuite/g++.dg/pph/incsame.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/incsame.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/incsame.cc	(working copy)
***************
*** 1,5 ****
- struct T { int f; };
- struct T v
- #include "incsame.h"
- struct T w
- #include "incsame.h"
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/d1chained.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/d1chained.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/d1chained.cc	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ #include "c1chained1.h"
+ #include "c1chained2.h"
+ // { dg-error "Preprocessor state inconsistent for PPH" "" { xfail *-*-* } }
+ int x = TWO;
Index: gcc/testsuite/g++.dg/pph/x1hardlookup.h
===================================================================
*** gcc/testsuite/g++.dg/pph/x1hardlookup.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1hardlookup.h	(revision 0)
***************
*** 0 ****
--- 1,18 ----
+ #ifndef X1HARDLOOKUP_H
+ #define X1HARDLOOKUP_H
+ struct V { int a; static int b;};
+ namespace N {
+    int V;
+    struct C { };
+    int operator + (int i, C c);
+    C O;
+    int I(int arg)
+    { return arg + V; }
+    struct V w;
+    int x = V::b;
+ }
+ 
+ int V;
+ struct D { };
+ int operator + (int i, D d);
+ #endif
Index: gcc/testsuite/g++.dg/pph/y2overload.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/y2overload.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/y2overload.cc	(revision 0)
***************
*** 0 ****
--- 1,9 ----
+ #include "x2overload1.h"
+ #include "x2overload2.h"
+ #include "x2overload3.h"
+ // { dg-error "inconsistent overload resolution" "" { xfail *-*-* } }
+ 
+ int g()
+ {
+    return f();
+ }
Index: gcc/testsuite/g++.dg/pph/c1typerefs.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1typerefs.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1typerefs.h	(revision 0)
***************
*** 0 ****
--- 1,7 ----
+ #ifndef C1TYPEREFS_H
+ #define C1TYPEREFS_H
+ struct base {
+     int field;
+ };
+ base function();
+ #endif
Index: gcc/testsuite/g++.dg/pph/c1variables.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/c1variables.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1variables.cc	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ #include "c1variables.h"
+ int gbl_initial = 1;
+ const float gbl_init_const = 1.5;
+ const int gbl_manifest = 2;
Index: gcc/testsuite/g++.dg/pph/variables.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/variables.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/variables.cc	(working copy)
***************
*** 1,17 ****
- extern int gbl_init_extern;		// need body			pass
- extern int gbl_uninit_extern;		// head only			pass
- int gbl_tentative;			// need body			pass
- int gbl_initial = 1;			// need body			pass
- extern const int gbl_extern_const;	// head only			pass
- const float gbl_init_const = 1.5;	// need body			pass
- const int gbl_manifest = 2;		// lazy body	merge head	pass
- struct D {
-     static int mbr_init_plain;		// head only			pass
-     static int mbr_uninit_plain;	// head only			pass
-     static const int mbr_init_const;	// head only			pass
-     static const int mbr_uninit_const;	// head only			pass
-     static const int mbr_manifest = 3;	// lazy body	merge head	okay
- };
- int D::mbr_init_plain = 4;		// need body	merge body	pass
- int D::mbr_uninit_plain;		// need body	merge body	FAIL
- const int D::mbr_init_const = 5;	// need body	merge body	FAIL
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/cflow.h
===================================================================
*** gcc/testsuite/g++.dg/pph/cflow.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/cflow.h	(working copy)
***************
*** 1,13 ****
- #ifndef __CFLOW_H
- #define __CFLOW_H
- 
- extern void foo (void);
- 
- #define X	1
- #if defined X
- #include "inif.h"
- extern int var1;
- extern int var2;
- #endif
- #include "inif.h"
- #endif
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/simple1.h
===================================================================
*** gcc/testsuite/g++.dg/pph/simple1.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/simple1.h	(working copy)
***************
*** 1,11 ****
- #ifndef SIMPLE1_H
- #define SIMPLE1_H
- 
- #include "simple2.h"
- 
- inline int foo()
- {
-   assert(1);
- }
- 
- #endif
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/c2builtin2.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/c2builtin2.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/c2builtin2.cc	(revision 0)
***************
*** 0 ****
--- 1,3 ----
+ #include "a2builtin4.h"
+ #include "c2builtin5.h"
+ #include "c2builtin6.h"
Index: gcc/testsuite/g++.dg/pph/c2builtin3.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c2builtin3.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c2builtin3.h	(revision 0)
***************
*** 0 ****
--- 1,6 ----
+ #ifndef C2BUILTIN3_H
+ #define C2BUILTIN3_H
+ #include "c2builtin1.h"
+ const char *refile = VALUE(__FILE__);
+ const char *reline = VALUE(__LINE__);
+ #endif
Index: gcc/testsuite/g++.dg/pph/x1functions.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/x1functions.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1functions.cc	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ #include "x1functions.h"
+ int type::mbr_decl_then_def(int i)      // need body
+ { return mbr_decl_inline( i ); }
+ int type::mbr_inl_then_def(int i)       // lazy body
+ { return mbr_decl_then_def( i ); }
Index: gcc/testsuite/g++.dg/pph/c1multinc2.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1multinc2.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1multinc2.h	(revision 0)
***************
*** 0 ****
--- 1,8 ----
+ #ifndef C1MULTINC2
+ #define C1MULTINC2
+ #include "c1altinc1.h"
+ extern void foo (void);
+ extern int var1;
+ extern int var2;
+ #include "c1altinc1.h"
+ #endif
Index: gcc/testsuite/g++.dg/pph/emptyclass.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/emptyclass.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/emptyclass.cc	(working copy)
***************
*** 1,2 ****
- struct B {
- };
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/c2dupguard2.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c2dupguard2.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c2dupguard2.h	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ #ifndef C2DUPGUARD_H
+ #define C2DUPGUARD_H
+ extern int x;
+ #endif
Index: gcc/testsuite/g++.dg/pph/c1guarded3.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1guarded3.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1guarded3.h	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ #ifndef C1GUARDED3_H
+ #define C1GUARDED3_H
+ #include "c1guarded1.h"
+ type variable3;
+ #endif
Index: gcc/testsuite/g++.dg/pph/simplecall.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/simplecall.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/simplecall.cc	(working copy)
***************
*** 1,10 ****
- int H( int a, int b) {
- }
- 
- int I( int a, int b) {
-     return a+b;
- }
- 
- int F( int c, int d) {
-     return H(c, d) + I(c, d);
- }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/simple.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/simple.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/simple.cc	(working copy)
***************
*** 1,7 ****
- /* comment */
- #include "simple1.h"
- 
- int main()
- {
- 	return foo();
- }
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/invoke.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/invoke.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/invoke.cc	(working copy)
***************
*** 1,6 ****
- #include "invoke.h"
- #define outer(major, minor) inner(major, minor)
- 
- void outer(long one, short two) { }
- major(three);
- minor(four);
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/invoke.h
===================================================================
*** gcc/testsuite/g++.dg/pph/invoke.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/invoke.h	(working copy)
***************
*** 1,4 ****
- # define gnu_dev_major(dev) long dev
- # define gnu_dev_minor(dev) short dev
- # define major(dev) gnu_dev_major (dev)
- # define minor(dev) gnu_dev_minor (dev)
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/globalref.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/globalref.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/globalref.cc	(working copy)
***************
*** 1,7 ****
- typedef int type;
- type x = 2;
- type y = x;
- type f() { return x; }
- const type n = 3;
- const type m = 4;
- type a[n+m];
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/guarded3.h
===================================================================
*** gcc/testsuite/g++.dg/pph/guarded3.h	(revision 170223)
--- gcc/testsuite/g++.dg/pph/guarded3.h	(working copy)
***************
*** 1,8 ****
- #ifndef GUARDED3_H
- #define GUARDED3_H
- 
- #include "guarded1.h"
- 
- type variable3;
- 
- #endif
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/c1field.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1field.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1field.h	(revision 0)
***************
*** 0 ****
--- 1,7 ----
+ #ifndef C1FIELD_H
+ #define C1FIELD_H
+ typedef int language;
+ struct program {
+     language field;
+ };
+ #endif
Index: gcc/testsuite/g++.dg/pph/incmod.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/incmod.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/incmod.cc	(working copy)
***************
*** 1,9 ****
- struct T { int f; };
- #define NAME v
- #define VALUE 1
- #include "incmod.h"
- #undef NAME
- #define NAME w
- #undef VALUE
- #define VALUE 2
- #include "incmod.h"
--- 0 ----
Index: gcc/testsuite/g++.dg/pph/c1altinc1.h
===================================================================
*** gcc/testsuite/g++.dg/pph/c1altinc1.h	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1altinc1.h	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ #ifndef C1ALTINC1_H
+ #define C1ALTINC1_H
+ extern float f1;
+ #endif
Index: gcc/testsuite/g++.dg/pph/x1variables.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/x1variables.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/x1variables.cc	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ #include "x1variables.h"
+ int D::mbr_init_plain = 4;
+ int D::mbr_uninit_plain;
+ const int D::mbr_init_const = 5;
Index: gcc/testsuite/g++.dg/pph/c1typerefs.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/c1typerefs.cc	(revision 0)
--- gcc/testsuite/g++.dg/pph/c1typerefs.cc	(revision 0)
***************
*** 0 ****
--- 1,7 ----
+ #include "c1typerefs.h"
+ int base_from_var() {
+     base variable;
+ }
+ int base_from_func() {
+     function();
+ }
Index: gcc/testsuite/g++.dg/pph/tmplsimple.cc
===================================================================
*** gcc/testsuite/g++.dg/pph/tmplsimple.cc	(revision 170223)
--- gcc/testsuite/g++.dg/pph/tmplsimple.cc	(working copy)
***************
*** 1,11 ****
- template< typename T >
- struct C {
-     int* b;
-     int method();
-     int another()
-     { return 1; }
- };
- template< typename T >
- int C< T >::method()
- { return 1; }
- C<int> v;
--- 0 ----
Index: gcc/cp/pph.c
===================================================================
*** gcc/cp/pph.c	(revision 170223)
--- gcc/cp/pph.c	(working copy)
*************** pth_file_change (cpp_reader *reader, con
*** 1898,1904 ****
  }
  
  
! /* Record a #include or #include_next.  */
  
  static void
  pth_include_handler (cpp_reader *reader ATTRIBUTE_UNUSED,
--- 1898,1952 ----
  }
  
  
! /* Write PPH output file.  */
! 
! static void
! write_pph_output (void)
! {
!   FILE *stream;
! 
!   if (flag_pph_debug >= 1)
!     fprintf (pph_logfile, "PPH: Writing %s\n", pph_out_file);
! 
!   stream = fopen (pph_out_file, "w");
!   if (!stream)
!     fatal_error ("Cannot open PPH file for writing: %s: %m", pph_out_file);
! 
!   fprintf (stream, "%s\n", pph_out_file);
!   fclose (stream);
! }
! 
! /* Read PPH file.  */
! 
! static void
! read_pph_file (const char* filename)
! {
!   FILE *stream;
!   char *line;
!   char *eol;
!   char linebuf[2*MAXPATHLEN];
! 
!   if (flag_pph_debug >= 1)
!     fprintf (pph_logfile, "PPH: Reading %s\n", filename);
! 
!   stream = fopen (filename, "r");
!   if (!stream)
!     fatal_error ("Cannot open PPH file for reading: %s: %m", filename);
! 
!   line = fgets (linebuf, sizeof linebuf, stream);
!   if (line == NULL)
!     fatal_error ("No line in PPH file %s: ", filename);
! 
!   eol = strchr (line, '\n');
!   *eol = '\0';
! 
!   if (strcmp (filename, line) != 0)
!     fatal_error ("Wrong content in PPH file %s: ", filename);
! 
!   fclose (stream);
! }
! 
! /* Record a #include or #include_next for PTH.  */
  
  static void
  pth_include_handler (cpp_reader *reader ATTRIBUTE_UNUSED,
*************** pth_include_handler (cpp_reader *reader 
*** 1928,1933 ****
--- 1976,2006 ----
    state->new_iname = name;
  }
  
+ /* Record a #include or #include_next for PPH.  */
+ 
+ static void
+ pph_include_handler (cpp_reader *reader ATTRIBUTE_UNUSED,
+                      location_t loc ATTRIBUTE_UNUSED,
+                      const unsigned char *dname,
+                      const char *name,
+                      int angle_brackets,
+                      const cpp_token **tok_p ATTRIBUTE_UNUSED)
+ {
+   const char *pph_file;
+ 
+   if (flag_pph_debug >= 1)
+     {
+       fprintf (pph_logfile, "PPH: #%s", dname);
+       fprintf (pph_logfile, " %c", angle_brackets ? '<' : '"');
+       fprintf (pph_logfile, "%s", name);
+       fprintf (pph_logfile, "%c\n", angle_brackets ? '>' : '"');
+     }
+ 
+   pph_file = query_pph_include_map (name);
+   if (pph_file != NULL)
+     read_pph_file (pph_file);
+ }
+ 
  
  /* The initial order of the size of the lexical lookaside table,
     which will accomodate as many as half of its slots in use.  */
*************** pph_free_catcher_memory (void)
*** 2148,2154 ****
  cp_token *
  pph_start_exposed (cp_parser *parser)
  {
!   if (flag_pph_debug >= 1)
      {
        timevar_push (TV_PPH_MANAGE);
  
--- 2221,2227 ----
  cp_token *
  pph_start_exposed (cp_parser *parser)
  {
!   if (flag_pph_debug >= 2)
      {
        timevar_push (TV_PPH_MANAGE);
  
*************** pph_copy_decls_outof_cache (VEC(tree, he
*** 2363,2369 ****
  void
  pph_stop_exposed (cp_parser *parser, cp_token *first_token)
  {
!   if (flag_pph_debug >= 1 && !VEC_empty (tree, pph_tree_catcher))
      {
        cp_token *last_token;
  
--- 2436,2442 ----
  void
  pph_stop_exposed (cp_parser *parser, cp_token *first_token)
  {
!   if (flag_pph_debug >= 2 && !VEC_empty (tree, pph_tree_catcher))
      {
        cp_token *last_token;
  
*************** pph_print_stats (void)
*** 3996,4001 ****
--- 4069,4076 ----
  void
  pph_init (void)
  {
+   cpp_callbacks *cb;
+ 
    if (flag_pph_logfile)
      {
        pph_logfile = fopen (flag_pph_logfile, "w");
*************** pph_init (void)
*** 4004,4009 ****
--- 4079,4090 ----
      }
    else
      pph_logfile = stdout;
+ 
+   if (flag_pph_debug >= 1)
+     fprintf (pph_logfile, "PPH: Initializing.\n");
+ 
+   cb = cpp_get_callbacks (parse_in);
+   cb->include = pph_include_handler;
  }
  
  
*************** pph_init (void)
*** 4012,4017 ****
--- 4093,4101 ----
  void
  pph_finish (void)
  {
+   if (pph_out_file != NULL)
+     write_pph_output ();
+ 
    if (flag_pph_stats)
      pph_print_stats ();
  
Index: gcc/cp/parser.c
===================================================================
*** gcc/cp/parser.c	(revision 170223)
--- gcc/cp/parser.c	(working copy)
*************** cp_lexer_new_main (void)
*** 384,389 ****
--- 384,399 ----
        pth_init (lexer);
        cp_lexer_get_tokens (lexer);
      }
+   else if (pph_out_file != NULL || query_have_pph_map ())
+     {
+       /* FIXME pph.  PPH is incompatible with PCH, so do not read ahead to
+ 	 the first token looking for a PCH pragma.  This convoluted
+ 	 initialization could be simplified if PCH was implemented in
+ 	 terms of the incremental compiler.  */
+       lexer = cp_lexer_alloc ();
+       pph_init ();
+       cp_lexer_get_tokens (lexer);
+     }
    else
      {
        /* FIXME pph.  Get rid of this duplicate and call cp_lexer_get_tokens
*************** c_parse_file (void)
*** 25151,25157 ****
      }
    already_called = true;
  
-   pph_init ();
    the_parser = cp_parser_new ();
    push_deferring_access_checks (flag_access_control
  				? dk_no_deferred : dk_no_check);
--- 25161,25166 ----
Index: gcc/Makefile.in
===================================================================
*** gcc/Makefile.in	(revision 170223)
--- gcc/Makefile.in	(working copy)
*************** GCC_OBJS = gcc.o opts-common.o gcc-optio
*** 1154,1160 ****
  # Language-specific object files shared by all C-family front ends.
  C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
    c-family/c-format.o c-family/c-gimplify.o c-family/c-lex.o \
!   c-family/c-omp.o c-family/c-opts.o c-family/c-pch.o \
    c-family/c-ppoutput.o c-family/c-pragma.o c-family/c-pretty-print.o \
    c-family/c-semantics.o c-family/c-ada-spec.o
  
--- 1154,1160 ----
  # Language-specific object files shared by all C-family front ends.
  C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
    c-family/c-format.o c-family/c-gimplify.o c-family/c-lex.o \
!   c-family/c-omp.o strstrmap.o c-family/c-opts.o c-family/c-pch.o \
    c-family/c-ppoutput.o c-family/c-pragma.o c-family/c-pretty-print.o \
    c-family/c-semantics.o c-family/c-ada-spec.o
  
*************** c-family/c-omp.o : c-family/c-omp.c $(CO
*** 2132,2138 ****
  
  c-family/c-opts.o : c-family/c-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
          $(TREE_H) $(C_PRAGMA_H) $(FLAGS_H) toplev.h langhooks.h \
!         $(DIAGNOSTIC_H) intl.h debug.h $(C_COMMON_H)	\
          $(OPTS_H) $(OPTIONS_H) $(MKDEPS_H) incpath.h cppdefault.h
  	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
  		$< $(OUTPUT_OPTION) @TARGET_SYSTEM_ROOT_DEFINE@
--- 2132,2138 ----
  
  c-family/c-opts.o : c-family/c-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
          $(TREE_H) $(C_PRAGMA_H) $(FLAGS_H) toplev.h langhooks.h \
!         $(DIAGNOSTIC_H) intl.h debug.h $(C_COMMON_H) strstrmap.h \
          $(OPTS_H) $(OPTIONS_H) $(MKDEPS_H) incpath.h cppdefault.h
  	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
  		$< $(OUTPUT_OPTION) @TARGET_SYSTEM_ROOT_DEFINE@
*************** s-bversion: BASE-VER
*** 2805,2810 ****
--- 2805,2814 ----
  	echo "#define BUILDING_GCC_VERSION (BUILDING_GCC_MAJOR * 1000 + BUILDING_GCC_MINOR)" >> bversion.h
  	$(STAMP) s-bversion
  
+ strstrmap.o: strstrmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+    $(srcdir)/../include/libiberty.h $(srcdir)/../include/hashtab.h \
+    strstrmap.h
+ 
  input.o : input.c $(CONFIG_H) $(SYSTEM_H) coretypes.h intl.h $(INPUT_H)
  
  toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \