2012-03-01 Lawrence Crowl <crowl@google.com>
* lib/dg-pph.exp: Change search for dg-xfail-if to xfail-if.
* g++.dg/pph/d0include-next.h: Put dg-warning in comment.
* g++.dg/pph/x2incomplete4.cc: Add documentary xfail-if.
* g++.dg/pph/x4incomplete4321.cc: Change documentary to xfail-if.
* g++.dg/pph/x4tmplclass2.cc: Change documentary to xfail-if.
* g++.dg/pph/x4tmplfuncinln.cc: Mark pph asm xokay.
* g++.dg/pph/x4tmplfuncninl.cc: Mark pph asm xokay.
* g++.dg/pph/x5dynarray7.h: Add documentary xfail-if.
* g++.dg/pph/x6dynarray3.cc: Add documentary xfail-if.
* g++.dg/pph/x6dynarray4.cc: Change to xfail on included pph.
* g++.dg/pph/x6dynarray5.h: Change to xfail on included pph.
* g++.dg/pph/x6dynarray6.h: Add documentary xfail-if.
* g++.dg/pph/x6rtti.cc: Remove excess-errors filter. Add bogus rtti mismatch. Make xfail-if documentary.
* g++.dg/pph/x7dynarray5.cc: Change to xfail on included pph. (The bogus void intrinsic comes fail-over to reading the textual header.)
* g++.dg/pph/x7dynarray6.cc: Change to xfail on bogus void intrinsic.
* g++.dg/pph/x7dynarray7.cc: Remove excess-errors filter. Add bogus void intrinsic. Change xfail-if message.
* g++.dg/pph/x7rtti.cc: Add documentary xfail-if. Separate failures to separate statements. Put dg-bogus on offending lines.
* g++.dg/pph/z4nontrivinit.cc: Change documentary to xfail-if.
* g++.dg/pph/z4tmplclass1.cc: Change in failing asm output. Change documentary to xfail-if.
* g++.dg/pph/z4tmplclass2.cc: Change in failing asm output. Change documentary to xfail-if.
* g++.dg/pph/z4tmplfuncinln.cc: Mark pph asm xokay.
* g++.dg/pph/z4tmplfuncninl.cc: Mark pph asm xokay.
2012-03-01 Lawrence Crowl <crowl@google.com>
* pph-core.c (pph_include_handler): Make warning message a single line.
* Make-lang.in (cp/pt.o): Depend on strptrmap.h.
* pph.h (pph_out_merge_key_tree): Made extern.
(pph_in_string): Made extern.
(typedef pph_merge_searcher): New.
(pph_in_merge_key_tree_with_searcher): Made extern.
(pph_out_pending_templates_list): Removed.
(pph_out_spec_entry_tables): Removed.
(pph_in_pending_templates_list): Removed.
(pph_in_spec_entry_tables): Removed.
(pph_out_merge_key_template_state): New.
(pph_out_merge_body_template_state): New.
(pph_in_merge_key_template_state): New.
(pph_in_merge_body_template_state): New.
* pt.c (#include "strptrmap.h"): New.
(pph_out_pending_templates_list): Move dump to higher level.
(pph_in_pending_templates_list): Make static.
(pph_out_key_spec_entry_slot): New.
(pph_out_spec_entry_slot): Renamed to pph_out_body_spec_entry_slot.
(pph_out_spec_entry_htab): Make slot function a parameter.
(pph_in_search_key_spec): New.
(pph_in_keys_spec_entry_htab): New.
(pph_in_spec_entry_htab): Rename to pph_in_bodies_spec_entry_htab.
(pph_out_merge_key_template_state): New.
(pph_out_spec_entry_tables): Rename to
pph_out_merge_body_template_state. Pass search functions. Add call
to pph_out_pending_templates_list. Move dumping here.
(static strptrmap_t *decl_spec_tbl): New.
(static strptrmap_t *type_spec_tbl): New.
(pph_in_merge_key_template_state): New.
(pph_in_spec_entry_tables): Rename to pph_in_merge_body_template_state.
Add call to pph_in_pending_templates_list. Move dumping here.
* pph-out.c (pph_out_merge_key_tree): Made extern. Added bool
parameter to force merge name emission, which is used for template
type specialization merging.
(pph_out_global_binding): Split into pph_out_global_binding_keys and
pph_out_global_binding_bodies.
(pph_write_file): Change calls for emitting global bindings and
template state.
* pph-in.c (pph_in_string): Make extern.
(pph_in_merge_key_tree): Factor out searching into function parameter.
Rename to pph_in_merge_key_tree_with_searcher. Always merge trees
when a match is found. Make extern.
(pph_in_search_key_decl_on_chain): New.
(pph_in_merge_key_decl_on_chain): New.
(pph_in_search_key_type_in_field): New.
(pph_in_merge_key_type_in_field): New.
(pph_in_global_binding): Split into pph_in_global_binding_keys and
pph_in_global_binding_bodies.
(pph_read_file_1): Change calls for emitting global bindings and
template state.
2012-03-01 Lawrence Crowl <crowl@google.com>
* strptrmap.h: New.
* strptrmap.c: New.
* Makefile.in: Added entries for strptrmap.h and strptrmap.c.
===================================================================
@@ -145,7 +145,7 @@ proc dg-pph-pos { subdir test options ma
if { ![file_on_host exists "$bname.s"] } {
# Expect assembly to be missing when the compile is an
# expected fail.
- if { ![llength [grep $test "dg-xfail-if.*-fpph-map"]]
+ if { ![llength [grep $test "xfail-if.*-fpph-map"]]
&& ![llength [grep $test "dg-bogus.*error:"]] } {
fail "$nshort $options (pph assembly missing)"
}
===================================================================
@@ -1,5 +1,5 @@
-// { dg-xfail-if "ICE instantiate_decl - bad merge" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "internal compiler error: in instantiate_decl, at cp/pt.c" "" { xfail *-*-* } 0 }
+// pph asm xokay 51578
+
#include "x0tmplfuncninl1.h"
#include "x0tmplfuncninl2.h"
#include "a0tmplfuncninl_u.h"
===================================================================
@@ -1,5 +1,5 @@
-// { dg-xfail-if "ICE instantiate_decl - bad merge" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "internal compiler error: in instantiate_decl, at cp/pt.c" "" { xfail *-*-* } 0 }
+// pph asm xokay 14419
+
#include "x0tmplfuncninl3.h"
#include "x0tmplfuncninl4.h"
#include "a0tmplfuncninl_u.h"
===================================================================
@@ -1,3 +1,4 @@
+// { xfail-if "BOGUS NEW OVERLOAD" { "*-*-*" } { "-fpph-map=pph.map" } }
// { dg-bogus "a0dynarray-dcl3.hi:11:60: error: call of overloaded 'operator new" "" { xfail *-*-* } 0 }
#include "x5dynarray3.h"
===================================================================
@@ -1,4 +1,5 @@
// pph asm xdiff 21766
+// xfail-if BOGUS XTRAFUN
// copies::copies() is wrongly generated
#include "x1incomplete3.h"
===================================================================
@@ -1,9 +1,8 @@
-// { dg-xfail-if "BOGUS POSSIBLY DROPPING SYMBOLS " { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "internal compiler error: canonical types differ for identical types" "" { xfail *-*-* } 0 }
-// { dg-excess-errors "type mismatch errors due to TYPE_CANONICAL problems." }
+// { xfail-if "DEPENDENT" { "*-*-*" } { "-fpph-map=pph.map" } }
+// { dg-bogus "ext/atomicity.h:48:61: error: void value not ignored as it ought to be" "" { xfail *-*-* } 0 }
#include "x0dynarray4.h"
-#include "x6dynarray5.h"
+#include "x6dynarray5.h" // { dg-bogus "warning: cannot open PPH file x6dynarray5.pph" "" { xfail *-*-* } }
#include <algorithm>
#include <iostream>
===================================================================
@@ -1,7 +1,6 @@
-// { dg-xfail-if "BOGUS MERGING" { "*-*-*" } { "-fpph-map=pph.map" } }
-// Too many failures to diagnose.
+// { xfail-if "DEPENDENT" { "*-*-*" } { "-fpph-map=pph.map" } }
-#include "x6dynarray5.h"
+#include "x6dynarray5.h" // { dg-bogus "cannot open PPH file x6dynarray5.pph" "" { xfail *-*-* } }
#include <algorithm>
===================================================================
@@ -1,3 +1,10 @@
+// { dg-xfail-if "UNIMPL TRAIT MANGLING" { "*-*-*" } { "-fpph-map=pph.map" } }
+// { dg-bogus "bits/stl_uninitialized.h:178:12: sorry, unimplemented: mangling trait_expr" "" { xfail *-*-* } 0 }
+// { dg-bogus "bits/allocator.h:153:12: sorry, unimplemented: mangling trait_expr" "" { xfail *-*-* } 0 }
+// { dg-bogus "bits/stl_construct.h:98:12: sorry, unimplemented: mangling trait_expr" "" { xfail *-*-* } 0 }
+// { dg-bogus "bits/stl_tempbuf.h:183:12: sorry, unimplemented: mangling trait_expr" "" { xfail *-*-* } 0 }
+// { dg-bogus "bits/cpp_type_traits.h:87:12: internal compiler error: in write_template_arg_literal, at cp/mangle.c:2919" "" { xfail *-*-* } 0 }
+
#ifndef X6DYNARRAY5_H
#define X6DYNARRAY5_H
===================================================================
@@ -1,5 +1,6 @@
-// { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-excess-errors "Embedded text merging problems" }
+// { dg-xfail-if "BOGUS INTRINSIC RETURN" { "*-*-*" } { "-fpph-map=pph.map" } }
+// { dg-bogus "ext/atomicity.h:48:61: error: void value not ignored as it ought to be" "" { xfail *-*-* } 0 }
+
#include <algorithm>
#include <iostream>
===================================================================
@@ -1,21 +1,21 @@
-// { dg-xfail-if "rtti problems" { *-*-* } { "-fpph-map=pph.map" } }
-// { dg-excess-errors "macro redefinition and operator match problems" }
-
+// { xfail-if "UNKNOWN MACRO AND BOGUS RTTI" { "*-*-*" } { "-fpph-map=pph.map" } }
+// { dg-bogus "x7rtti.cc:9:0: warning: .__STDC_IEC_559_COMPLEX__. redefined" "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:9:0: warning: .__STDC_ISO_10646__. redefined" "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:9:0: warning: .__STDC_IEC_559__. redefined" "" { xfail *-*-* } 0 }
// FIXME pph: This should be a { dg=do run } (with '=' replaced by '-')
+
#include "x5rtti1.h"
#include "x5rtti2.h"
int main()
{
- if (poly1() == poly2()
- && nonp1() == nonp2()
- && hpol1() == hpol2()
- && hnpl1() == hnpl2()
- && poly1() != nonp1()
- && hpol1() == hnpl1()
- && poly2() != nonp2()
- && hpol2() == hnpl2())
- return 0;
- else
- return 1;
+ bool a = poly1() == poly2(); // { dg-bogus "no match for 'operator=='" "" { xfail *-*-* } }
+ bool b = nonp1() == nonp2(); // { dg-bogus "no match for 'operator=='" "" { xfail *-*-* } }
+ bool c = hpol1() == hpol2(); // { dg-bogus "no match for 'operator=='" "" { xfail *-*-* } }
+ bool d = hnpl1() == hnpl2(); // { dg-bogus "no match for 'operator=='" "" { xfail *-*-* } }
+ bool e = poly1() != nonp1(); // { dg-bogus "no match for 'operator!='" "" { xfail *-*-* } }
+ bool f = hpol1() == hnpl1(); // { dg-bogus "no match for 'operator=='" "" { xfail *-*-* } }
+ bool g = poly2() != nonp2(); // { dg-bogus "no match for 'operator!='" "" { xfail *-*-* } }
+ bool h = hpol2() == hnpl2(); // { dg-bogus "no match for 'operator=='" "" { xfail *-*-* } }
+ return !(a && b && c && d && e && f && g && h);
}
===================================================================
@@ -1,5 +1,5 @@
-// pph asm xdiff 43522
-// xfail DUPVAR DUPFUNC
+// pph asm xdiff 54665
+// xfail-if BOGUS DUPFUNC
#include "x0tmplclass13.h"
#include "x0tmplclass14.h"
===================================================================
@@ -2,5 +2,5 @@
/* We do not support #include_next in PPH images. */
#ifndef D0INCLUDE_NEXT_H
#define D0INCLUDE_NEXT_H
-#include_next "d0include-next.h" { dg-warning ".*PPH generation disabled" }
+#include_next "d0include-next.h" // { dg-warning ".*PPH generation disabled" }
#endif
===================================================================
@@ -1,3 +1,4 @@
+// { xfail-if "INTRINSIC RETURN" { "*-*-*" } { "-fpph-map=pph.map" } }
// { dg-bogus "atomicity.h:48:61: error: void value not ignored as it ought to be" "" { xfail *-*-* } 0 }
#ifndef X6DYNARRAY6_H
===================================================================
@@ -1,5 +1,6 @@
-// { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-excess-errors "Embedded text merging problems" }
+// { dg-xfail-if "BOGUS INTRINSIC RETURN" { "*-*-*" } { "-fpph-map=pph.map" } }
+// { dg-bogus "ext/atomicity.h:48:61: error: void value not ignored as it ought to be" "" { xfail *-*-* } 0 }
+
#include <algorithm>
#include <iostream>
===================================================================
@@ -1,5 +1,5 @@
-// { dg-xfail-if "ICE instantiate_decl - bad merge" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "internal compiler error: in instantiate_decl, at cp/pt.c" "" { xfail *-*-* } 0 }
+// pph asm xokay 14419
+
#include "x0tmplfuncinln1.h"
#include "x0tmplfuncinln2.h"
#include "a0tmplfuncinln_u.h"
===================================================================
@@ -1,5 +1,5 @@
-// { dg-xfail-if "ICE instantiate_decl - bad merge" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "internal compiler error: in instantiate_decl, at cp/pt.c" "" { xfail *-*-* } 0 }
+// pph asm xokay 14419
+
#include "x0tmplfuncinln3.h"
#include "x0tmplfuncinln4.h"
#include "a0tmplfuncinln_u.h"
===================================================================
@@ -1,5 +1,5 @@
-// pph asm xdiff 26423
-// xfail DUPVAR DUPFUNC
+// pph asm xdiff 44158
+// xfail-if BOGUS DUPVAR DUPFUNC
#include "x0tmplclass23.h"
#include "x0tmplclass24.h"
===================================================================
@@ -1,5 +1,5 @@
// pph asm xdiff 46966
-// xfail BOGUS DOUBLE DYNINIT
+// xfail-if BOGUS DOUBLE DYNINIT
#include "x0nontrivinit1.h"
#include "x0nontrivinit2.h"
===================================================================
@@ -1,5 +1,6 @@
// pph asm xdiff 64351
-// XFAIL missing constructors
+// xfail-if BOGUS MISSFUN
+// missing constructors
#include "x0incomplete3.h"
#include "x0incomplete2.h"
===================================================================
@@ -1,5 +1,5 @@
// pph asm xdiff 51443
-// xfail DUPFUNC
+// xfail-if BOGUS DUPFUNC
#include "x0tmplclass21.h"
#include "x0tmplclass22.h"
===================================================================
@@ -1,3 +1,4 @@
+// { xfail-if "INTRINSIC RETURN" { "*-*-*" } { "-fpph-map=pph.map" } }
// { dg-bogus "atomicity.h:48:61: error: void value not ignored as it ought to be" "" { xfail *-*-* } 0 }
#ifndef X5DYNARRAY7_H
===================================================================
@@ -1,10 +1,11 @@
-// { dg-xfail-if "rtti problems" { *-*-* } { "-fpph-map=pph.map" } }
-// { dg-excess-errors "operator match problems due to type merging." }
+// { xfail-if "BOGUS RTTI" { "*-*-*" } { "-fpph-map=pph.map" } }
// FIXME pph - We should make this a run test.
#include "x5rtti1.h"
int main()
{
- return poly1() != nonp1() && hpol1() == hnpl1();
+ bool a = poly1() != nonp1(); // { dg-bogus "no match for 'operator!='" "" { xfail *-*-* } }
+ bool b = hpol1() == hnpl1(); // { dg-bogus "no match for 'operator=='" "" { xfail *-*-* } }
+ return !(a && b);
}
===================================================================
@@ -839,7 +839,7 @@ pph_include_handler (cpp_reader *reader,
read_text_file_p = false;
else
warning_at (loc, OPT_Wmissing_pph,
- "cannot open PPH file %s for reading: %m\n"
+ "cannot open PPH file %s for reading: %m; "
"using original header %s", pph_file, name);
}
===================================================================
@@ -323,7 +323,7 @@ cp/except.o: cp/except.c $(CXX_TREE_H) $
cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(TM_P_H)
cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h cp/cp-objcp-common.h \
toplev.h $(TREE_INLINE_H) pointer-set.h gt-cp-pt.h vecprim.h intl.h \
- c-family/c-objc.h $(CXX_PPH_H)
+ c-family/c-objc.h $(CXX_PPH_H) strptrmap.h
cp/error.o: cp/error.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_H) \
$(FLAGS_H) $(REAL_H) $(LANGHOOKS_DEF_H) $(CXX_PRETTY_PRINT_H) \
tree-diagnostic.h tree-pretty-print.h pointer-set.h c-family/c-objc.h
===================================================================
@@ -153,6 +153,7 @@ extern void pph_out_uint (pph_stream *st
extern void pph_out_location (pph_stream *stream, location_t loc);
extern void pph_out_tree (pph_stream *stream, tree t);
extern void pph_out_tree_vec (pph_stream *stream, VEC(tree,gc) *v);
+extern void pph_out_merge_key_tree (pph_stream *, tree, bool);
extern void pph_out_record_marker (pph_stream *stream,
enum pph_record_marker marker, enum pph_tag tag);
void pph_add_decl_to_symtab (tree, enum pph_symtab_action, bool, bool);
@@ -160,7 +161,12 @@ void pph_add_decl_to_symtab (tree, enum
/* In pph-in.c. */
extern unsigned int pph_in_uint (pph_stream *stream);
extern location_t pph_in_location (pph_stream *stream);
+extern const char *pph_in_string (pph_stream *stream);
extern tree pph_in_tree (pph_stream *stream);
+typedef tree (*pph_merge_searcher)(pph_stream *stream, tree read_expr,
+ const char **name, void *holder);
+extern tree pph_in_merge_key_tree_with_searcher (pph_stream *stream,
+ void *holder, pph_merge_searcher searcher);
extern VEC(tree,gc) *pph_in_tree_vec (pph_stream *stream);
extern void pph_union_into_tree_vec (VEC(tree,gc) **into, VEC(tree,gc) *from);
extern enum pph_record_marker pph_in_record_marker (pph_stream *stream,
@@ -179,10 +185,10 @@ extern struct binding_table_s *pph_in_bi
extern void pph_set_global_identifier_bindings (void);
/* In pt.c. */
-extern void pph_out_pending_templates_list (pph_stream *);
-extern void pph_out_spec_entry_tables (pph_stream *);
-extern void pph_in_pending_templates_list (pph_stream *);
-extern void pph_in_spec_entry_tables (pph_stream *);
+extern void pph_out_merge_key_template_state (pph_stream *);
+extern void pph_out_merge_body_template_state (pph_stream *);
+extern void pph_in_merge_key_template_state (pph_stream *);
+extern void pph_in_merge_body_template_state (pph_stream *);
/* FIXME pph: These functions should be moved to tree.c on merge. */
extern VEC(tree,heap) *chain2vec (tree chain); /* In pph-out.c. */
===================================================================
@@ -37,13 +37,6 @@ along with GCC; see the file COPYING3.
#include "parser.h"
-/****************************************************** forward declarations */
-
-
-/* Forward declarations to avoid circular references. */
-static void pph_out_merge_key_tree (pph_stream *, tree);
-
-
/***************************************************** stream initialization */
@@ -1012,7 +1005,7 @@ pph_out_merge_key_vec (pph_stream *strea
tree t;
pph_out_hwi (stream, VEC_length (tree, v));
FOR_EACH_VEC_ELT_REVERSE (tree, v, i, t)
- pph_out_merge_key_tree (stream, t);
+ pph_out_merge_key_tree (stream, t, false);
}
@@ -2274,8 +2267,8 @@ pph_out_merge_body_namespace_decl (pph_s
/* Write the merge key for tree EXPR to STREAM. */
-static void
-pph_out_merge_key_tree (pph_stream *stream, tree expr)
+void
+pph_out_merge_key_tree (pph_stream *stream, tree expr, bool name_type)
{
if (pph_out_start_merge_key_tree_record (stream, expr))
return;
@@ -2299,11 +2292,13 @@ pph_out_merge_key_tree (pph_stream *stre
tree type = TREE_TYPE (expr);
pph_out_bool (stream, is_implicit);
if (is_implicit)
- pph_out_merge_key_tree (stream, type);
+ pph_out_merge_key_tree (stream, type, false);
}
}
else
{
+ if (name_type)
+ pph_out_merge_name (stream, expr);
gcc_assert (TYPE_P (expr));
}
@@ -2580,10 +2575,10 @@ pph_out_identifiers (pph_stream *stream,
}
-/* Write the global bindings in scope_chain to STREAM. */
+/* Write the keys for global bindings in scope_chain to STREAM. */
static void
-pph_out_global_binding (pph_stream *stream)
+pph_out_global_binding_keys (pph_stream *stream)
{
cp_binding_level *bl;
@@ -2618,6 +2613,15 @@ pph_out_global_binding (pph_stream *stre
/* Emit all the merge keys for objects that need to be merged when
reading multiple PPH images. */
pph_out_merge_key_binding_level (stream, bl);
+}
+
+
+/* Write the bodies for global bindings in scope_chain to STREAM. */
+
+static void
+pph_out_global_binding_bodies (pph_stream *stream)
+{
+ cp_binding_level *bl = scope_chain->bindings;
/* Now emit all the bodies. */
pph_out_merge_body_binding_level (stream, bl);
@@ -2642,19 +2646,17 @@ pph_write_file (pph_stream *stream)
idents_used = cpp_lt_capture (parse_in);
pph_out_identifiers (stream, &idents_used);
- /* Emit the bindings for the global namespace. */
- pph_out_global_binding (stream);
+ /* Emit the bindings for namespace scopes and template state. */
+ pph_out_global_binding_keys (stream);
+ pph_out_merge_key_template_state (stream);
+ pph_out_global_binding_bodies (stream);
+ pph_out_merge_body_template_state (stream);
/* Emit other global state kept by the parser. FIXME pph, these
globals should be fields in struct cp_parser. */
pph_out_tree (stream, keyed_classes);
pph_out_tree_vec (stream, unemitted_tinfo_decls);
-
- pph_out_pending_templates_list (stream);
- pph_out_spec_entry_tables (stream);
-
pph_out_tree (stream, static_aggregates);
-
pph_out_decl2_hidden_state (stream);
/* Emit the symbol table. */
===================================================================
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.
#include "timevar.h"
#include "tree-iterator.h"
#include "vecprim.h"
+#include "strptrmap.h"
/* The type of functions taking a tree, and some additional data, and
returning an int. */
@@ -20681,9 +20682,6 @@ pph_out_pending_templates_list (pph_stre
int count = 0;
struct pending_template *cur;
- if (flag_pph_dump_tree)
- pph_dump_pending_templates_list (stderr);
-
/* Count the number of items. */
for (cur = pending_templates; cur != NULL; cur = cur->next )
++count;
@@ -20696,7 +20694,7 @@ pph_out_pending_templates_list (pph_stre
/* Load and merge the pending_templates list from STREAM. */
-void
+static void
pph_in_pending_templates_list (pph_stream *stream)
{
unsigned count = pph_in_uint (stream);
@@ -20715,17 +20713,27 @@ pph_in_pending_templates_list (pph_strea
pending_templates = pt;
last_pending_template = pt;
}
+}
- if (flag_pph_dump_tree)
- pph_dump_pending_templates_list (stderr);
+
+/* A callback of htab_traverse. Writes out the PPH the merge keys for SLOT
+ using the AUXillary information. */
+
+static int
+pph_out_key_spec_entry_slot (void **slot, void *aux)
+{
+ pph_stream *stream = (pph_stream *)aux;
+ struct spec_entry *entry = (struct spec_entry *) *slot;
+ pph_out_merge_key_tree (stream, entry->spec, true);
+ return 1;
}
-/* A callback of htab_traverse. Just extracts a (type) tree from SLOT
- and writes it out for PPH using the AUXillary information. */
+/* A callback of htab_traverse. Writes out the PPH the merge bodies for SLOT
+ using the AUXillary information. */
static int
-pph_out_spec_entry_slot (void **slot, void *aux)
+pph_out_body_spec_entry_slot (void **slot, void *aux)
{
pph_stream *stream = (pph_stream *)aux;
struct spec_entry *entry = (struct spec_entry *) *slot;
@@ -20735,16 +20743,18 @@ pph_out_spec_entry_slot (void **slot, vo
return 1;
}
-/* Emit a spec_entry TABLE to STREAM. */
+
+/* Write a spec_entry TABLE to STREAM using FUNC. */
static void
-pph_out_spec_entry_htab (pph_stream *stream, htab_t *table)
+pph_out_spec_entry_htab (pph_stream *stream, htab_t *table,
+ int (*func)(void **slot, void *aux))
{
if (*table)
{
/*FIXME pph: This write may be unstable. */
pph_out_uint (stream, htab_elements (*table));
- htab_traverse_noresize (*table, pph_out_spec_entry_slot, stream);
+ htab_traverse_noresize (*table, func, stream);
}
else
pph_out_uint (stream, 0);
@@ -20766,7 +20776,8 @@ pph_dump_spec_entry_slot (void **slot, v
return 1;
}
-/* Dump a spec_entry TABLE to STREAM. */
+
+/* Dump keys in spec_entry TABLE to STREAM. */
static void
pph_dump_spec_entry_htab (FILE *stream, const char *name, htab_t *table)
@@ -20781,14 +20792,50 @@ pph_dump_spec_entry_htab (FILE *stream,
fprintf (stream, "PPH: NULL %s spec_entry elements\n", name);
}
-/* Load and merge a spec_entry TABLE from STREAM. */
+
+/* Search for a decl or type key READ_EXPR within the specialization name
+ table HOLDER. Read the name necessary for that search from STREAM and
+ update *NAME_P with the string found. */
+
+static tree
+pph_in_search_key_spec (pph_stream *stream, tree read_expr,
+ const char **name_p, void *holder)
+{
+ tree expr;
+ strptrmap_t *spec_tbl = (strptrmap_t*)holder;
+ *name_p = pph_in_string (stream);
+ expr = (tree)strptrmap_insert (spec_tbl, *name_p, read_expr);
+ if (expr)
+ return expr;
+ else
+ return read_expr;
+}
+
+
+/* Load merge keys for a spec_entry TABLE from STREAM. */
static void
-pph_in_spec_entry_htab (pph_stream *stream, htab_t *table)
+pph_in_keys_spec_entry_htab (pph_stream *stream, pph_merge_searcher searcher,
+ strptrmap_t *spec_tbl)
{
unsigned count = pph_in_uint (stream);
if (flag_pph_debug >= 2)
- fprintf (pph_logfile, "PPH: loading %d spec_entries\n", count );
+ fprintf (pph_logfile, "PPH: loading keys for %d spec_entries\n", count );
+ for (; count > 0; --count)
+ {
+ pph_in_merge_key_tree_with_searcher (stream, (void*)spec_tbl, searcher);
+ }
+}
+
+
+/* Load merge bodies for a spec_entry TABLE from STREAM. */
+
+static void
+pph_in_bodies_spec_entry_htab (pph_stream *stream, htab_t *table)
+{
+ unsigned count = pph_in_uint (stream);
+ if (flag_pph_debug >= 2)
+ fprintf (pph_logfile, "PPH: loading bodies %d spec_entries\n", count );
for (; count > 0; --count)
{
hashval_t hash;
@@ -20804,30 +20851,69 @@ pph_in_spec_entry_htab (pph_stream *stre
}
-/* Emit all spec_entry tables to STREAM. */
+/* Write merge keys for template state to STREAM. */
void
-pph_out_spec_entry_tables (pph_stream *stream)
+pph_out_merge_key_template_state (pph_stream *stream ATTRIBUTE_UNUSED)
{
- pph_out_spec_entry_htab (stream, &decl_specializations);
- if (flag_pph_dump_tree)
- pph_dump_spec_entry_htab (pph_logfile, "decl", &decl_specializations);
- pph_out_spec_entry_htab (stream, &type_specializations);
- if (flag_pph_dump_tree)
- pph_dump_spec_entry_htab (pph_logfile, "type", &type_specializations);
+ pph_out_spec_entry_htab (stream, &decl_specializations,
+ pph_out_key_spec_entry_slot);
+ pph_out_spec_entry_htab (stream, &type_specializations,
+ pph_out_key_spec_entry_slot);
}
-/* Load and merge all spec_entry tables from STREAM. */
+
+/* Write merge bodies for template state to STREAM. */
void
-pph_in_spec_entry_tables (pph_stream *stream)
+pph_out_merge_body_template_state (pph_stream *stream)
{
- pph_in_spec_entry_htab (stream, &decl_specializations);
+ pph_out_spec_entry_htab (stream, &decl_specializations,
+ pph_out_body_spec_entry_slot);
+ pph_out_spec_entry_htab (stream, &type_specializations,
+ pph_out_body_spec_entry_slot);
+ pph_out_pending_templates_list (stream);
if (flag_pph_dump_tree)
- pph_dump_spec_entry_htab (pph_logfile, "decl", &decl_specializations);
- pph_in_spec_entry_htab (stream, &type_specializations);
+ {
+ pph_dump_spec_entry_htab (pph_logfile, "decl", &decl_specializations);
+ pph_dump_spec_entry_htab (pph_logfile, "type", &type_specializations);
+ pph_dump_pending_templates_list (stderr);
+ }
+}
+
+
+/* Tables for merging decl and type specializations. */
+
+static strptrmap_t *decl_spec_tbl = strptrmap_create ();
+static strptrmap_t *type_spec_tbl = strptrmap_create ();
+
+
+/* Read merge keys for template state from STREAM. */
+
+void
+pph_in_merge_key_template_state (pph_stream *stream ATTRIBUTE_UNUSED)
+{
+ pph_in_keys_spec_entry_htab (stream, pph_in_search_key_spec,
+ decl_spec_tbl);
+ pph_in_keys_spec_entry_htab (stream, pph_in_search_key_spec,
+ type_spec_tbl);
+}
+
+
+/* Read merge keys for template state from STREAM. */
+
+void
+pph_in_merge_body_template_state (pph_stream *stream)
+{
+ pph_in_bodies_spec_entry_htab (stream, &decl_specializations);
+ pph_in_bodies_spec_entry_htab (stream, &type_specializations);
+ pph_in_pending_templates_list (stream);
if (flag_pph_dump_tree)
- pph_dump_spec_entry_htab (pph_logfile, "type", &type_specializations);
+ {
+ pph_dump_spec_entry_htab (pph_logfile, "type", &type_specializations);
+ pph_dump_spec_entry_htab (pph_logfile, "decl", &decl_specializations);
+ pph_dump_pending_templates_list (stderr);
+ }
}
===================================================================
@@ -2914,7 +2914,11 @@ write_template_arg_literal (const tree v
switch (TREE_CODE (value))
{
case CONST_DECL:
- write_integer_cst (DECL_INITIAL (value));
+ {
+ tree initial = DECL_INITIAL (value);
+ gcc_assert (TREE_CODE (initial) == INTEGER_CST);
+ write_integer_cst (value);
+ }
break;
case INTEGER_CST:
===================================================================
@@ -50,7 +50,8 @@ DEF_VEC_ALLOC_P(char_p,heap);
/* Forward declarations to avoid circularity. */
-static tree pph_in_merge_key_tree (pph_stream *, tree *);
+static tree pph_in_merge_key_decl_on_chain (pph_stream *, tree *);
+static tree pph_in_merge_key_type_in_var (pph_stream *, tree *);
/***************************************************** stream initialization */
@@ -193,7 +194,7 @@ pph_in_bytes (pph_stream *stream, void *
/* Read and return a string from STREAM. */
-static const char *
+const char *
pph_in_string (pph_stream *stream)
{
const char *s = streamer_read_string (stream->encoder.r.data_in,
@@ -859,7 +860,7 @@ pph_in_merge_key_chain (pph_stream *stre
count = pph_in_hwi (stream);
for (i = 0; i < count; i++)
- pph_in_merge_key_tree (stream, chain);
+ pph_in_merge_key_decl_on_chain (stream, chain);
}
@@ -884,7 +885,7 @@ pph_in_merge_body_chain (pph_stream *str
address.
This TOC is indexed by two values: the merge key read by
- pph_in_merge_key_tree and the context in which we are doing this
+ pph_in_merge_key_decl_on_chain and the context in which we are doing this
merge. */
static htab_t merge_toc = NULL;
@@ -2535,13 +2536,14 @@ pph_merge_tree_attributes (tree expr, tr
}
-/* Read a merge key from STREAM. If CHAIN is not NULL and the merge
- key read from STREAM is not found in *CHAIN, the newly allocated
- tree is added to it. If no CHAIN is given, then the tree is just
- allocated and added to the pickle cache. */
+/* Read a merge key from STREAM,
+ using the SEARCHER to find a matching existing tree within HOLDER.
+ If the search succeeds, merge into the existing tree and use that.
+ In any event, the resulting tree is added to the pickle cache. */
-static tree
-pph_in_merge_key_tree (pph_stream *stream, tree *chain)
+tree
+pph_in_merge_key_tree_with_searcher (pph_stream *stream, void *holder,
+ pph_merge_searcher searcher)
{
enum pph_record_marker marker;
unsigned image_ix, ix;
@@ -2560,28 +2562,14 @@ pph_in_merge_key_tree (pph_stream *strea
language-independent bitfields for the new tree. */
read_expr = pph_in_tree_header (stream, &fully_read_p);
gcc_assert (!fully_read_p);
- gcc_assert (chain);
+ gcc_assert (holder);
- if (DECL_P (read_expr))
- {
- name = pph_in_string (stream);
- /* If we are merging into an existing CHAIN. Look for a match in
- CHAIN to READ_EXPR's header. If we found a match, EXPR will be
- the existing tree that matches READ_EXPR. Otherwise, EXPR is the
- newly allocated READ_EXPR. */
- expr = pph_merge_into_chain (read_expr, name, chain);
- if (expr != read_expr)
- pph_merge_tree_attributes (expr, read_expr);
- }
- else
- {
- gcc_assert (TYPE_P (read_expr));
- if (*chain)
- expr = *chain;
- else
- expr = read_expr;
- }
+ expr = searcher (stream, read_expr, &name, holder);
gcc_assert (expr != NULL);
+
+ if (expr != read_expr)
+ pph_merge_tree_attributes (expr, read_expr);
+
pph_cache_insert_at (&stream->cache, expr, ix,
pph_tree_code_to_tag (expr));
@@ -2596,7 +2584,7 @@ pph_in_merge_key_tree (pph_stream *strea
{
bool is_implicit = pph_in_bool (stream);
if (is_implicit)
- pph_in_merge_key_tree (stream, &(TREE_TYPE (expr)));
+ pph_in_merge_key_type_in_var (stream, &(TREE_TYPE (expr)));
}
}
else
@@ -2612,6 +2600,60 @@ pph_in_merge_key_tree (pph_stream *strea
}
+/* Search in HOLDER for an existing decl that matches READ_EXPR.
+ Read the match string from STREAM and assign to *NAME_P. */
+
+static tree
+pph_in_search_key_decl_on_chain (pph_stream *stream, tree read_expr,
+ const char **name_p, void *holder)
+{
+ gcc_assert (DECL_P (read_expr));
+ *name_p = pph_in_string (stream);
+ /* If we are merging into an existing CHAIN. Look for a match in
+ CHAIN to READ_EXPR's header. If we found a match, EXPR will be
+ the existing tree that matches READ_EXPR. Otherwise, EXPR is the
+ newly allocated READ_EXPR. */
+ return pph_merge_into_chain (read_expr, *name_p, (tree*)holder);
+}
+
+
+/* Read a decl merge key from STREAM and search for matches on the CHAIN. */
+
+static tree
+pph_in_merge_key_decl_on_chain (pph_stream *stream, tree *chain)
+{
+ return pph_in_merge_key_tree_with_searcher (stream, (void*) chain,
+ pph_in_search_key_decl_on_chain);
+}
+
+
+/* Search in HOLDER for an existing type that matches READ_EXPR.
+ The HOLDER is its decl's type field. */
+
+static tree
+pph_in_search_key_type_in_field (pph_stream *stream ATTRIBUTE_UNUSED,
+ tree read_expr, const char **name_p ATTRIBUTE_UNUSED, void *holder)
+{
+ tree *field = (tree*)holder;
+ gcc_assert (TYPE_P (read_expr));
+ if (*field)
+ return *field;
+ else
+ return read_expr;
+}
+
+
+/* Read a type merge key from STREAM and search for matches in its decl's
+ type field. */
+
+static tree
+pph_in_merge_key_type_in_var (pph_stream *stream, tree *field)
+{
+ return pph_in_merge_key_tree_with_searcher (stream, (void*) field,
+ pph_in_search_key_type_in_field);
+}
+
+
/* Read and return a tree from STREAM. */
tree
@@ -3017,12 +3059,12 @@ pph_in_identifiers (pph_stream *stream,
}
-/* Read global bindings from STREAM and merge them into
+/* Read keys global bindings from STREAM and merge them into
scope_chain->bindings. Bindings are merged at every level starting
at the global bindings from STREAM. */
static void
-pph_in_global_binding (pph_stream *stream)
+pph_in_global_binding_keys (pph_stream *stream)
{
cp_binding_level *bl, *other_bl;
bool existed_p;
@@ -3041,6 +3083,17 @@ pph_in_global_binding (pph_stream *strea
same slot IX that the writer used, the trees read now will be
bound to scope_chain->bindings. */
pph_in_merge_key_binding_level (stream, &bl);
+}
+
+
+/* Read global bindings from STREAM and merge them into
+ scope_chain->bindings. Bindings are merged at every level starting
+ at the global bindings from STREAM. */
+
+static void
+pph_in_global_binding_bodies (pph_stream *stream)
+{
+ cp_binding_level *bl = scope_chain->bindings;
/* Once all the symbols and types at every binding level have been
merged to the corresponding binding levels in the current
@@ -3119,20 +3172,18 @@ pph_read_file_1 (pph_stream *stream)
working towards an identical line_table in pph and non-pph. */
cpp_lt_replay (parse_in, &idents_used, &cpp_token_replay_loc);
- /* Read the bindings from STREAM. */
- pph_in_global_binding (stream);
+ /* Read the namespace scope bindings and template state from STREAM. */
+ pph_in_global_binding_keys (stream);
+ pph_in_merge_key_template_state (stream);
+ pph_in_global_binding_bodies (stream);
+ pph_in_merge_body_template_state (stream);
/* Read and merge the other global state collected during parsing of
the original header. */
pph_union_into_chain (&keyed_classes, pph_in_tree (stream));
pph_union_into_tree_vec (&unemitted_tinfo_decls, pph_in_tree_vec (stream));
-
- pph_in_pending_templates_list (stream);
- pph_in_spec_entry_tables (stream);
-
file_static_aggregates = pph_in_tree (stream);
static_aggregates = chainon (file_static_aggregates, static_aggregates);
-
pph_in_decl2_hidden_state (stream);
/* Read and process the symbol table. */
===================================================================
@@ -0,0 +1,175 @@
+/* A string to string mapping.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ Contributed by Lawrence Crowl <crowl@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 "strptrmap.h"
+
+/* The hash table slot type. */
+
+typedef struct strptrhashslot_d
+{
+ const char *key;
+ void *val;
+} strptrhashslot_t;
+
+/* Returns a hash code for the slot v.
+ Function type is typedef hashval_t (*htab_hash) (const void *); */
+
+static hashval_t
+strptrhashslot_hash (const void *v)
+{
+ const strptrhashslot_t *s = (const strptrhashslot_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
+strptrhashslot_eq (const void *v1, const void *v2)
+{
+ const strptrhashslot_t *s1 = (const strptrhashslot_t *) v1;
+ const strptrhashslot_t *s2 = (const strptrhashslot_t *) v2;
+ return strcmp (s1->key, s2->key) == 0;
+}
+
+/* Free the slot V. */
+
+static void
+strptrhashslot_free (void *v)
+{
+ strptrhashslot_t *s = (strptrhashslot_t *) v;
+ free (CONST_CAST (void *, (const void *) s->key));
+ free (v);
+}
+
+/* The type for the hash table itself. */
+
+struct strptrmap_d
+{
+ htab_t tab;
+};
+
+/* Create a hash table. */
+
+strptrmap_t*
+strptrmap_create (void)
+{
+ strptrmap_t *tbl;
+ htab_t tab;
+ tbl = XCNEW (strptrmap_t);
+ gcc_assert (tbl != NULL);
+ tab = htab_create (37, strptrhashslot_hash,
+ strptrhashslot_eq, strptrhashslot_free);
+ gcc_assert (tab != NULL);
+ tbl->tab = tab;
+ return tbl;
+}
+
+/* Destroy the hash table TBL. */
+
+void
+strptrmap_destroy (strptrmap_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 NOT been replaced. */
+
+void *
+strptrmap_insert (strptrmap_t *tbl, const char *key, void *val)
+{
+ strptrhashslot_t query;
+ strptrhashslot_t **spot;
+ void* result;
+
+ gcc_assert (tbl != NULL);
+ gcc_assert (key != NULL);
+
+ query.key = key;
+ query.val = val;
+ spot = (strptrhashslot_t **) htab_find_slot (tbl->tab, &query, INSERT);
+
+ if (*spot == NULL)
+ {
+ /* We found no instance of key in the table. */
+ strptrhashslot_t *entry
+ = (strptrhashslot_t *) xmalloc (sizeof (strptrhashslot_t));
+ entry->key = xstrdup (key);
+ entry->val = val;
+ *spot = entry;
+ result = NULL;
+ }
+ else
+ {
+ /* We found an instance of key already in the table. */
+ strptrhashslot_t *entry = (strptrhashslot_t *)*spot;
+ result = entry->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. */
+
+void*
+strptrmap_lookup (strptrmap_t* tbl, const char* key)
+{
+ strptrhashslot_t query;
+ strptrhashslot_t **spot;
+ void* result;
+
+ gcc_assert (tbl != NULL);
+ gcc_assert (key != NULL);
+
+ query.key = key;
+ spot = (strptrhashslot_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. */
+ strptrhashslot_t *entry = (strptrhashslot_t *)*spot;
+ gcc_assert (entry != NULL);
+ result = entry->val;
+ }
+
+ return result;
+}
===================================================================
@@ -0,0 +1,27 @@
+/* A string to string mapping.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ Contributed by Lawrence Crowl <crowl@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 strptrmap_d strptrmap_t;
+
+extern strptrmap_t* strptrmap_create (void);
+extern void strptrmap_destroy (strptrmap_t *tbl);
+extern void* strptrmap_insert (strptrmap_t *tbl, const char *key, void *val);
+extern void* strptrmap_lookup (strptrmap_t *tbl, const char *key);
===================================================================
@@ -1350,6 +1350,7 @@ OBJS = \
store-motion.o \
streamer-hooks.o \
stringpool.o \
+ strptrmap.o \
strstrmap.o \
target-globals.o \
targhooks.o \
@@ -2748,6 +2749,10 @@ s-bversion: BASE-VER
echo "#define BUILDING_GCC_VERSION (BUILDING_GCC_MAJOR * 1000 + BUILDING_GCC_MINOR)" >> bversion.h
$(STAMP) s-bversion
+strptrmap.o: strptrmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(srcdir)/../include/libiberty.h $(srcdir)/../include/hashtab.h \
+ strptrmap.h
+
strstrmap.o: strstrmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(srcdir)/../include/libiberty.h $(srcdir)/../include/hashtab.h \
strstrmap.h