diff mbox

[pph] Do not call pushdecl_into_namespace to re-register symbols (issue4685053)

Message ID 20110711212620.0EE141DA197@topo.tor.corp.google.com
State New
Headers show

Commit Message

Diego Novillo July 11, 2011, 9:26 p.m. UTC
This patch changes the way we re-register symbols as they are read
from the PPH image.  Instead of calling pushdecl...(), we merge the
global bindings from the PPH file (scope_chain->bindings) into the
global bindings of the current translation unit.

This fixes 3 name lookup failures in the testsuite: c2eabi1.cc,
c2meteor-contest.cc and x1namespace.cc.  It does produce a new failure
in x1tmplclass.cc, which is addressed in the 3rd patch in this series.

Tested on x86_64.  Applied to branch.


Diego.

        * pph-streamer-in.c (pph_register_decls_in_symtab): Rename
	from pph_add_bindings_to_namespace.
	Do not call pushdecl_into_namespace for every symbol.  Just
	reset the scope for its identifier's namespace binding.
	(pph_in_scope_chain): Merge every field in struct
	cp_binding_level from the scope_chain->bindings coming from
	STREAM and the current scope_chain->bindings.

testsuite/ChangeLog.pph

	* g++.dg/pph/c2eabi1.cc: Remove XFAIL markers.  Expect an
	assembly difference.
	* g++.dg/pph/c2meteor-contest.cc: Likewise.
	* g++.dg/pph/x1namespace.cc: Mark fixed.



--
This patch is available for review at http://codereview.appspot.com/4685053
diff mbox

Patch

diff --git a/gcc/cp/ChangeLog.pph b/gcc/cp/ChangeLog.pph
index 37b8464..1011902 100644
--- a/gcc/cp/ChangeLog.pph
+++ b/gcc/cp/ChangeLog.pph
@@ -1,3 +1,13 @@ 
+2011-07-07   Diego Novillo  <dnovillo@google.com>
+
+	* pph-streamer-in.c (pph_register_decls_in_symtab): Rename
+	from pph_add_bindings_to_namespace.
+	Do not call pushdecl_into_namespace for every symbol.  Just
+	reset the scope for its identifier's namespace binding.
+	(pph_in_scope_chain): Merge every field in struct
+	cp_binding_level from the scope_chain->bindings coming from
+	STREAM and the current scope_chain->bindings.
+
 2011-07-06   Diego Novillo  <dnovillo@google.com>
 
 	* pph-streamer-out.c (pph_out_scope_chain): Fix formatting.
diff --git a/gcc/cp/pph-streamer-in.c b/gcc/cp/pph-streamer-in.c
index 0bab93b..571ebf5 100644
--- a/gcc/cp/pph-streamer-in.c
+++ b/gcc/cp/pph-streamer-in.c
@@ -1139,38 +1139,32 @@  pph_in_lang_type (pph_stream *stream)
 }
 
 
-/* Add all bindings declared in BL to NS.  */
+/* Register all the symbols in binding level BL in the callgraph symbol
+   table.  NS is the namespace where all the symbols in BL live.  */
 
 static void
-pph_add_bindings_to_namespace (struct cp_binding_level *bl, tree ns)
+pph_register_decls_in_symtab (struct cp_binding_level *bl, tree ns)
 {
-  tree t, chain;
+  tree t;
 
   /* The chains are built backwards (ref: add_decl_to_level),
      reverse them before putting them back in.  */
   bl->names = nreverse (bl->names);
   bl->namespaces = nreverse (bl->namespaces);
 
-  for (t = bl->names; t; t = chain)
-    {
-      /* Pushing a decl into a scope clobbers its DECL_CHAIN.
-	 Preserve it.  */
-      chain = DECL_CHAIN (t);
-      pushdecl_into_namespace (t, ns);
+  for (t = bl->names; t; t = DECL_CHAIN (t))
+    if (DECL_NAME (t) && IDENTIFIER_NAMESPACE_BINDINGS (DECL_NAME (t)))
+      {
+	cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (DECL_NAME (t));
+	b->scope = NAMESPACE_LEVEL (ns);
 
-      if (TREE_CODE (t) == VAR_DECL && TREE_STATIC (t) && !DECL_EXTERNAL (t))
-	varpool_finalize_decl (t);
-    }
+	if (TREE_CODE (t) == VAR_DECL && TREE_STATIC (t) && !DECL_EXTERNAL (t))
+	  varpool_finalize_decl (t);
+      }
 
-  for (t = bl->namespaces; t; t = chain)
-    {
-      /* Pushing a decl into a scope clobbers its DECL_CHAIN.
-	 Preserve it.  */
-      chain = DECL_CHAIN (t);
-      pushdecl_into_namespace (t, ns);
-      if (NAMESPACE_LEVEL (t))
-	pph_add_bindings_to_namespace (NAMESPACE_LEVEL (t), t);
-    }
+  for (t = bl->namespaces; t; t = DECL_CHAIN (t))
+    if (NAMESPACE_LEVEL (t))
+      pph_register_decls_in_symtab (NAMESPACE_LEVEL (t), t);
 }
 
 
@@ -1179,12 +1173,56 @@  pph_add_bindings_to_namespace (struct cp_binding_level *bl, tree ns)
 static void
 pph_in_scope_chain (pph_stream *stream)
 {
-  struct cp_binding_level *pph_bindings;
+  struct saved_scope *file_scope_chain;
+  unsigned i;
+  tree decl;
+  cp_class_binding *cb;
+  cp_label_binding *lb;
+  struct cp_binding_level *cur_bindings, *new_bindings;
+
+  file_scope_chain = ggc_alloc_cleared_saved_scope ();
+  file_scope_chain->bindings = new_bindings = pph_in_binding_level (stream);
+  cur_bindings = scope_chain->bindings;
+
+  pph_register_decls_in_symtab (new_bindings, global_namespace);
+
+  /* Merge the bindings from STREAM into saved_scope->bindings.  */
+  chainon (cur_bindings->names, new_bindings->names);
+  chainon (cur_bindings->namespaces, new_bindings->namespaces);
+
+  for (i = 0; VEC_iterate (tree, new_bindings->static_decls, i, decl); i++)
+    VEC_safe_push (tree, gc, cur_bindings->static_decls, decl);
+
+  chainon (cur_bindings->usings, new_bindings->usings);
+  chainon (cur_bindings->using_directives, new_bindings->using_directives);
+
+  for (i = 0;
+       VEC_iterate (cp_class_binding, new_bindings->class_shadowed, i, cb);
+       i++)
+    VEC_safe_push (cp_class_binding, gc, cur_bindings->class_shadowed, cb);
+
+  chainon (cur_bindings->type_shadowed, new_bindings->type_shadowed);
+
+  for (i = 0;
+       VEC_iterate (cp_label_binding, new_bindings->shadowed_labels, i, lb);
+       i++)
+    VEC_safe_push (cp_label_binding, gc, cur_bindings->shadowed_labels, lb);
+
+  chainon (cur_bindings->blocks, new_bindings->blocks);
+
+  gcc_assert (cur_bindings->this_entity == new_bindings->this_entity);
+  gcc_assert (cur_bindings->level_chain == new_bindings->level_chain);
+  gcc_assert (cur_bindings->dead_vars_from_for
+	      == new_bindings->dead_vars_from_for);
 
-  pph_bindings = pph_in_binding_level (stream);
+  chainon (cur_bindings->statement_list, new_bindings->statement_list);
 
-  /* Merge the bindings obtained from STREAM in the global namespace.  */
-  pph_add_bindings_to_namespace (pph_bindings, global_namespace);
+  gcc_assert (cur_bindings->binding_depth == new_bindings->binding_depth);
+  gcc_assert (cur_bindings->kind == new_bindings->kind);
+  gcc_assert (cur_bindings->explicit_spec_p == new_bindings->explicit_spec_p);
+  gcc_assert (cur_bindings->keep == new_bindings->keep);
+  gcc_assert (cur_bindings->more_cleanups_ok == new_bindings->more_cleanups_ok);
+  gcc_assert (cur_bindings->have_cleanups == new_bindings->have_cleanups);
 }
 
 
diff --git a/gcc/testsuite/ChangeLog.pph b/gcc/testsuite/ChangeLog.pph
index da45f01..4c0d8f6 100644
--- a/gcc/testsuite/ChangeLog.pph
+++ b/gcc/testsuite/ChangeLog.pph
@@ -1,3 +1,10 @@ 
+2011-07-07  Diego Novillo  <dnovillo@google.com>
+
+	* g++.dg/pph/c2eabi1.cc: Remove XFAIL markers.  Expect an
+	assembly difference.
+	* g++.dg/pph/c2meteor-contest.cc: Likewise.
+	* g++.dg/pph/x1namespace.cc: Mark fixed.
+
 2011-07-05  Diego Novillo  <dnovillo@google.com>
 
 	* g++.dg/pph/x2nontrivinit.cc: Mark fixed.
diff --git a/gcc/testsuite/g++.dg/pph/c2eabi1.cc b/gcc/testsuite/g++.dg/pph/c2eabi1.cc
index 96ee8eb..968cec7 100644
--- a/gcc/testsuite/g++.dg/pph/c2eabi1.cc
+++ b/gcc/testsuite/g++.dg/pph/c2eabi1.cc
@@ -1,6 +1,5 @@ 
-// { dg-timeout 3 { target *-*-* } }
-// { dg-xfail-if "INFINITE" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-options "-w -fpermissive" }
+/* { dg-options "-w" } */
+// pph asm xdiff
 
 #include "c2eabi1.h"
 
diff --git a/gcc/testsuite/g++.dg/pph/c2meteor-contest.cc b/gcc/testsuite/g++.dg/pph/c2meteor-contest.cc
index e35cca4..1841806 100644
--- a/gcc/testsuite/g++.dg/pph/c2meteor-contest.cc
+++ b/gcc/testsuite/g++.dg/pph/c2meteor-contest.cc
@@ -1,6 +1,7 @@ 
-/* { dg-timeout 2 { target *-*-* } }  */
-// { dg-xfail-if "INFINITE" { "*-*-*" } { "-fpph-map=pph.map" } }
 /* { dg-options "-w" }  */
+
+// pph asm xdiff
+
 #include "c2meteor-contest.h"
 
 int main(int argc, char **argv) {
diff --git a/gcc/testsuite/g++.dg/pph/x1namespace.cc b/gcc/testsuite/g++.dg/pph/x1namespace.cc
index 92cd248..6101c70 100644
--- a/gcc/testsuite/g++.dg/pph/x1namespace.cc
+++ b/gcc/testsuite/g++.dg/pph/x1namespace.cc
@@ -1,7 +1,3 @@ 
-// { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "internal compiler error: in resume_scope" "" { xfail *-*-* } 0 }
-// { dg-prune-output "In file included from " }
-
 #include "x1namespace.h"
 
 namespace A {