This patch addresses the problem of two template instantiations
appearing to be identical.  They differ in TEMPLATE_PARM_NUM_SIBLINGS,
and so that information needs to be pushed out to the template merge
name.

Test x1tmpldfltparm.cc is now passing the assert, though it has
unneeded functions emitted.

Tested on x64.


Index: gcc/testsuite/ChangeLog.pph

2012-03-22   Lawrence Crowl  <cr...@google.com>

        * g++.dg/pph/x1tmpldfltparm.cc: Failure change from merging to excess
        code generation.

Index: gcc/cp/ChangeLog.pph

2012-03-22   Diego Novillo  <dnovi...@google.com>

        * error.c (dump_location_qualifier):  Add qualifier using
        TEMPLATE_PARM_NUM_SIBLINGS.  Rename to dump_tmpl_type_parm_qualifier.
        (dump_tmpl_type_parm_qualifier): Renamed from above.
        (dump_type): Change call of dump_location_qualifier to
        dump_tmpl_type_parm_qualifier.
        * pt.c (pph_out_pending_templates_list):  Add more debugging output.
        (pph_in_pending_templates_list):  Move debugging output.
        (pph_out_spec_entry_htab):  Add more debugging output.
        * parser.c (cp_debug_parser_where):  Fix comment.
        (cp_debug_the_parser_where):  New.
        * parser.h (cp_debug_the_parser_where): New.


Index: gcc/testsuite/g++.dg/pph/x1tmpldfltparm.cc
===================================================================
--- gcc/testsuite/g++.dg/pph/x1tmpldfltparm.cc  (revision 185539)
+++ gcc/testsuite/g++.dg/pph/x1tmpldfltparm.cc  (working copy)
@@ -1,5 +1,5 @@
-// { dg-xfail-if "DEFAULT TEMPLATE ARG MERGING" { "*-*-*" } { 
"-fpph-map=pph.map" } }
-// { dg-bogus "Trying to merge distinct trees from the same PPH image 
x0tmpldfltparm.pph" "" { xfail *-*-* } 0 }
+// {    xfail-if "EXCESS FUNCTIONS" { "*-*-*" } { "-fpph-map=pph.map" } }
+// pph asm xdiff 53613
 
 #include "x0tmpldfltparm.h"
 
Index: gcc/cp/error.c
===================================================================
--- gcc/cp/error.c      (revision 185539)
+++ gcc/cp/error.c      (working copy)
@@ -351,24 +351,30 @@ dump_alias_template_specialization (tree
 }
 
 
-/* Dump a location of a DECL as a qualifier, depending on FLAGS.  */
+/* Dump a discriminating qualifier for a template type parameter,
+   depending on FLAGS.  */
 
 static void
-dump_location_qualifier (tree decl, int flags)
+dump_tmpl_type_parm_qualifier (tree type, int flags)
 {
 if (flags & TFF_LOC_FOR_TEMPLATE_PARMS)
   {
+    tree decl = TYPE_NAME (type);
     expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (decl));
-    char *buffer = (char*)xmalloc (strlen (xloc.file) + 46);
+    char *buffer = (char*)xmalloc (strlen (xloc.file) + 60);
+    tree tmv = TYPE_MAIN_VARIANT (type);
+    tree tpi = TEMPLATE_TYPE_PARM_INDEX (tmv);
+    unsigned int sib = TEMPLATE_PARM_NUM_SIBLINGS (tpi);
     if (xloc.column != 0)
-      sprintf (buffer, "`%s:%d:%d`", xloc.file, xloc.line, xloc.column);
+      sprintf (buffer, "`%s:%d:%d#%d`", xloc.file, xloc.line, xloc.column, 
sib);
     else
-      sprintf (buffer, "`%s:%d`", xloc.file, xloc.line);
+      sprintf (buffer, "`%s:%d#%d`", xloc.file, xloc.line, sib);
     pp_cxx_ws_string (cxx_pp, buffer);
     free (buffer);
   }
 }
 
+
 /* Dump a human-readable equivalent of TYPE.  FLAGS controls the
    format.  */
 
@@ -488,7 +494,7 @@ dump_type (tree t, int flags)
        if (decl)
          {
            tree ident = DECL_NAME (decl);
-           dump_location_qualifier (decl, flags);
+           dump_tmpl_type_parm_qualifier (t, flags);
            if (ident)
              pp_cxx_tree_identifier (cxx_pp, ident);
            else
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c (revision 185539)
+++ gcc/cp/pt.c (working copy)
@@ -3546,6 +3546,7 @@ reduce_template_parm_level (tree index, 
   return TEMPLATE_PARM_DESCENDANTS (index);
 }
 
+
 /* Process information from new template parameter PARM and append it
    to the LIST being built.  This new parameter is a non-type
    parameter iff IS_NON_TYPE is true. This new parameter is a
@@ -20728,6 +20729,9 @@ pph_out_pending_templates_list (pph_stre
   for (cur = pending_templates; cur != NULL;  cur = cur->next )
     ++count;
 
+  if (flag_pph_debug >= 2)
+    fprintf (pph_logfile, "PPH: writing %d pending templates\n", count );
+
   /* Now emit them.  */
   pph_out_uint (stream, count);
   for (cur = pending_templates; cur != NULL;  cur = cur->next )
@@ -20740,11 +20744,13 @@ static void
 pph_in_pending_templates_list (pph_stream *stream)
 { 
   unsigned count = pph_in_uint (stream);
+
+  if (flag_pph_debug >= 2)
+    fprintf (pph_logfile, "PPH: loading %d pending templates\n", count );
+
   for (; count > 0; --count)
     {
       struct pending_template *pt;
-      if (flag_pph_debug >= 2)
-        fprintf (pph_logfile, "PPH: loading %d pending templates\n", count );
       pt = ggc_alloc_pending_template ();
       pt->next = NULL;
       pt->tinst = pph_in_tinst_level (stream);
@@ -20794,8 +20800,11 @@ pph_out_spec_entry_htab (pph_stream *str
 {
   if (*table)
     {
+      unsigned count = htab_elements (*table);
       /*FIXME pph: This write may be unstable.  */
-      pph_out_uint (stream, htab_elements (*table));
+      pph_out_uint (stream, count);
+      if (flag_pph_debug >= 2)
+        fprintf (pph_logfile, "PPH: writing %d spec_entries\n", count );
       htab_traverse_noresize (*table, func, stream);
     }
   else
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c     (revision 185539)
+++ gcc/cp/parser.c     (working copy)
@@ -463,9 +463,8 @@ cp_debug_parser_tokens (FILE *file, cp_p
 }
 
 
-/* Concisely dump the tokens around where the PARSER's current token
-   in a concise manner.  If FILE is NULL, the output is printed on
-   stderr. */
+/* Dump the tokens around where the PARSER's current token is.
+   If FILE is NULL, the output is printed on stderr. */
 
 void
 cp_debug_parser_where (FILE *file, cp_parser *parser)
@@ -503,6 +502,7 @@ cp_debug_parser_where (FILE *file, cp_pa
   cp_debug_parser_tokens (file, parser, window_size);
 }
 
+
 /* Dump debugging information for the given PARSER.  If FILE is NULL,
    the output is printed on stderr.  */
 
@@ -27290,6 +27290,16 @@ cp_parser_transaction_cancel (cp_parser 
 
 static GTY (()) cp_parser *the_parser;
 
+
+/* Dump the tokens around where the_parser's current token is.
+   If FILE is NULL, the output is printed on stderr. */
+
+void
+cp_debug_the_parser_where (FILE *file)
+{
+  cp_debug_parser_where (file, the_parser);
+}
+
 
 /* Special handling for the first token or line in the file.  The first
    thing in the file might be #pragma GCC pch_preprocess, which loads a
Index: gcc/cp/parser.h
===================================================================
--- gcc/cp/parser.h     (revision 185539)
+++ gcc/cp/parser.h     (working copy)
@@ -360,5 +360,6 @@ extern void cp_lexer_debug_tokens (VEC(c
 extern cp_token_cache *cp_token_cache_new (cp_token *, cp_token *);
 extern void cp_debug_parser (FILE *, cp_parser *);
 extern void cp_debug_parser_where (FILE *, cp_parser *);
+extern void cp_debug_the_parser_where (FILE *);
 
 #endif  /* GCC_CP_PARSER_H  */

--
This patch is available for review at http://codereview.appspot.com/5881052

Reply via email to