From patchwork Fri Mar 2 18:43:35 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lawrence Crowl X-Patchwork-Id: 144300 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 30913B6EEE for ; Sat, 3 Mar 2012 05:44:16 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1331318657; h=Comment: DomainKey-Signature:Received:Received:Received:Received: Received-SPF:Received:Received:MIME-Version:Received:Received: Received:Received:To:Subject:Message-Id:Date:From:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=zURxh5VkZOT8UAw9Q3IKdB6EL8s=; b=QEnFUzLbSCb+dh+O39C2NZuTMswJeUY28sR28iIj+YCRmgbJa9GuffpaGD7+Fy dx7D+uirzg6GxdeTQTJu614cinsGS/DiK7TgpnYxss8S3Ofbk2563PYegs6KTflO tDMOdJZima+FIvOKQUg2sotk1b7cprmqqRdFPFrJDTRsc= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received-SPF:Authentication-Results:Received:Received:MIME-Version:Received:Received:Received:Received:To:Subject:Message-Id:Date:From:X-Gm-Message-State:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=en2Q9wBoyRuDzAEecV6mLzPN2ZjoGVlSBz/KhPOok/bgNfOEvRmSz/kzM29E3z IXoonnT8wSJejal8FHZAVIGGGW2TA+lNKQB2sPeVFqLJnjaIYgQFyRBNb4v0LXmv WnV4mBJ5CFMORDzIxHbO9Maek5H5uZAgXE1iExLjbn61A=; Received: (qmail 25868 invoked by alias); 2 Mar 2012 18:44:10 -0000 Received: (qmail 25824 invoked by uid 22791); 2 Mar 2012 18:44:01 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_LOW, TW_BJ, TW_JC, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail-yw0-f73.google.com (HELO mail-yw0-f73.google.com) (209.85.213.73) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 02 Mar 2012 18:43:37 +0000 Received: by yhpp61 with SMTP id p61so238810yhp.2 for ; Fri, 02 Mar 2012 10:43:36 -0800 (PST) Received-SPF: pass (google.com: domain of crowl@google.com designates 10.236.190.68 as permitted sender) client-ip=10.236.190.68; Authentication-Results: mr.google.com; spf=pass (google.com: domain of crowl@google.com designates 10.236.190.68 as permitted sender) smtp.mail=crowl@google.com; dkim=pass header.i=crowl@google.com Received: from mr.google.com ([10.236.190.68]) by 10.236.190.68 with SMTP id d44mr18828927yhn.1.1330713816510 (num_hops = 1); Fri, 02 Mar 2012 10:43:36 -0800 (PST) Received: by 10.236.190.68 with SMTP id d44mr12171670yhn.1.1330713816495; Fri, 02 Mar 2012 10:43:36 -0800 (PST) MIME-Version: 1.0 Received: by 10.236.190.68 with SMTP id d44mr12171640yhn.1.1330713816252; Fri, 02 Mar 2012 10:43:36 -0800 (PST) Received: from wpzn3.hot.corp.google.com (216-239-44-65.google.com [216.239.44.65]) by gmr-mx.google.com with ESMTPS id d64si3508428yhn.3.2012.03.02.10.43.36 (version=TLSv1/SSLv3 cipher=AES128-SHA); Fri, 02 Mar 2012 10:43:36 -0800 (PST) Received: from jade.mtv.corp.google.com (jade.mtv.corp.google.com [172.18.110.116]) by wpzn3.hot.corp.google.com (Postfix) with ESMTP id E96A910004D; Fri, 2 Mar 2012 10:43:35 -0800 (PST) Received: by jade.mtv.corp.google.com (Postfix, from userid 21482) id 7F5BD2225E6; Fri, 2 Mar 2012 10:43:35 -0800 (PST) To: reply@codereview.appspotmail.com, dnovillo@google.com, gcc-patches@gcc.gnu.org Subject: [pph] Merge template specializations. (issue5726044) Message-Id: <20120302184335.7F5BD2225E6@jade.mtv.corp.google.com> Date: Fri, 2 Mar 2012 10:43:35 -0800 (PST) From: crowl@google.com (Lawrence Crowl) X-Gm-Message-State: ALoCoQnfgDfbZ79gwpwypNZAU5JYkuU9v7dbut2L2Mf+01QhaaFNredW3tsdnsKI2cfNqgZOptzjwDBqXil4EiKD7t3SHs/O0wBtdoDG55MpkD8gMvIE0CLr4a8txldGVkX6Kv9rrpjhHXF3QUU+e98nB1D/A8Wkpk7VddiMFvkZHkOB1BHIq88= X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This patch merges template specializations. * Factored searching out of pph_in_merge_key_tree via a function parameter. Its name is now pph_in_merge_key_tree_with_searcher. The decl searching now resides in pph_in_search_key_decl_on_chain and the type searching now resides in pph_in_search_key_type_in_var. Added two convenience functions pph_in_merge_key_decl_on_chain and pph_in_merge_key_type_in_var to enable concise replacement of calls to pph_in_merge_key_tree.. * Split pph_out/in_global_binding to place the specialization keys between the global keys and the global bodies. * Changed the template state in/out functions to be non-specific to specific tables, but specific to keys or bodies. * Added strptrmap.h and strptrmap.c for searching for existing specializations. * Several routines in pph-out.c and pph-in.c needed for specialization merging have been made extern for pt.c. The major test changes are as follows. * Several ICEs are now gone, most of which are replaced by other errors. * More instances of a bogus error on a void atomic intrinsic. * Unimplemented trait mangling in x6dynarray5.h, which also causes all includers to fail. * Test abi/mangle17.C changes behavior. It emits errors for the an equivalent but different piece of code. I will address this problem later. Test cleanups are as follows. * Some compilation failures add a 'documentary' xfail-if. The syntax is exactly like "dg-xfail-if", but without the "dg-". This change enables searching for "xfail-if". * Some assembly comparisons add or modify a 'xfail' comment to an 'xfail-if' comment. This change enables searching for "xfail-if". * The dg-pph.exp test controller now searches for xfail-if rather than dg-xfail-if to catch expected fails with no exess errors. * Some tests have had their xfail-if comment string clarified. * Some tests used dg-excess-errors. These have been removed in favor of stating the exact failures. * Some compilation dg-bogus patterns have been moved to the offending * Some compilation problems have been isolated to a single line and statement, which enables the above. line. * One test has changed trailing include text into a comment. Tested on x64. --- This patch is available for review at http://codereview.appspot.com/5726044 Index: gcc/testsuite/ChangeLog.pph 2012-03-01 Lawrence Crowl * 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. Index: gcc/cp/ChangeLog.pph 2012-03-01 Lawrence Crowl * 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. Index: gcc/ChangeLog.pph 2012-03-01 Lawrence Crowl * strptrmap.h: New. * strptrmap.c: New. * Makefile.in: Added entries for strptrmap.h and strptrmap.c. Index: gcc/testsuite/lib/dg-pph.exp =================================================================== --- gcc/testsuite/lib/dg-pph.exp (revision 184772) +++ gcc/testsuite/lib/dg-pph.exp (working copy) @@ -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)" } Index: gcc/testsuite/g++.dg/pph/x4tmplfuncninl.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x4tmplfuncninl.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/x4tmplfuncninl.cc (working copy) @@ -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" Index: gcc/testsuite/g++.dg/pph/z4tmplfuncninl.cc =================================================================== --- gcc/testsuite/g++.dg/pph/z4tmplfuncninl.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/z4tmplfuncninl.cc (working copy) @@ -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" Index: gcc/testsuite/g++.dg/pph/x6dynarray3.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x6dynarray3.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/x6dynarray3.cc (working copy) @@ -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" Index: gcc/testsuite/g++.dg/pph/x2incomplete4.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x2incomplete4.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/x2incomplete4.cc (working copy) @@ -1,4 +1,5 @@ // pph asm xdiff 21766 +// xfail-if BOGUS XTRAFUN // copies::copies() is wrongly generated #include "x1incomplete3.h" Index: gcc/testsuite/g++.dg/pph/x7dynarray5.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x7dynarray5.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/x7dynarray5.cc (working copy) @@ -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 #include Index: gcc/testsuite/g++.dg/pph/x6dynarray4.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x6dynarray4.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/x6dynarray4.cc (working copy) @@ -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 Index: gcc/testsuite/g++.dg/pph/x6dynarray5.h =================================================================== --- gcc/testsuite/g++.dg/pph/x6dynarray5.h (revision 184772) +++ gcc/testsuite/g++.dg/pph/x6dynarray5.h (working copy) @@ -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 Index: gcc/testsuite/g++.dg/pph/x7dynarray6.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x7dynarray6.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/x7dynarray6.cc (working copy) @@ -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 #include Index: gcc/testsuite/g++.dg/pph/x7rtti.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x7rtti.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/x7rtti.cc (working copy) @@ -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); } Index: gcc/testsuite/g++.dg/pph/z4tmplclass1.cc =================================================================== --- gcc/testsuite/g++.dg/pph/z4tmplclass1.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/z4tmplclass1.cc (working copy) @@ -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" Index: gcc/testsuite/g++.dg/pph/d0include-next.h =================================================================== --- gcc/testsuite/g++.dg/pph/d0include-next.h (revision 184772) +++ gcc/testsuite/g++.dg/pph/d0include-next.h (working copy) @@ -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 Index: gcc/testsuite/g++.dg/pph/x6dynarray6.h =================================================================== --- gcc/testsuite/g++.dg/pph/x6dynarray6.h (revision 184772) +++ gcc/testsuite/g++.dg/pph/x6dynarray6.h (working copy) @@ -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 Index: gcc/testsuite/g++.dg/pph/x7dynarray7.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x7dynarray7.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/x7dynarray7.cc (working copy) @@ -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 #include Index: gcc/testsuite/g++.dg/pph/x4tmplfuncinln.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x4tmplfuncinln.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/x4tmplfuncinln.cc (working copy) @@ -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" Index: gcc/testsuite/g++.dg/pph/z4tmplfuncinln.cc =================================================================== --- gcc/testsuite/g++.dg/pph/z4tmplfuncinln.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/z4tmplfuncinln.cc (working copy) @@ -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" Index: gcc/testsuite/g++.dg/pph/z4tmplclass2.cc =================================================================== --- gcc/testsuite/g++.dg/pph/z4tmplclass2.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/z4tmplclass2.cc (working copy) @@ -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" Index: gcc/testsuite/g++.dg/pph/z4nontrivinit.cc =================================================================== --- gcc/testsuite/g++.dg/pph/z4nontrivinit.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/z4nontrivinit.cc (working copy) @@ -1,5 +1,5 @@ // pph asm xdiff 46966 -// xfail BOGUS DOUBLE DYNINIT +// xfail-if BOGUS DOUBLE DYNINIT #include "x0nontrivinit1.h" #include "x0nontrivinit2.h" Index: gcc/testsuite/g++.dg/pph/x4incomplete4321.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x4incomplete4321.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/x4incomplete4321.cc (working copy) @@ -1,5 +1,6 @@ // pph asm xdiff 64351 -// XFAIL missing constructors +// xfail-if BOGUS MISSFUN +// missing constructors #include "x0incomplete3.h" #include "x0incomplete2.h" Index: gcc/testsuite/g++.dg/pph/x4tmplclass2.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x4tmplclass2.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/x4tmplclass2.cc (working copy) @@ -1,5 +1,5 @@ // pph asm xdiff 51443 -// xfail DUPFUNC +// xfail-if BOGUS DUPFUNC #include "x0tmplclass21.h" #include "x0tmplclass22.h" Index: gcc/testsuite/g++.dg/pph/x5dynarray7.h =================================================================== --- gcc/testsuite/g++.dg/pph/x5dynarray7.h (revision 184772) +++ gcc/testsuite/g++.dg/pph/x5dynarray7.h (working copy) @@ -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 Index: gcc/testsuite/g++.dg/pph/x6rtti.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x6rtti.cc (revision 184772) +++ gcc/testsuite/g++.dg/pph/x6rtti.cc (working copy) @@ -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); } Index: gcc/cp/pph-core.c =================================================================== --- gcc/cp/pph-core.c (revision 184772) +++ gcc/cp/pph-core.c (working copy) @@ -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); } Index: gcc/cp/Make-lang.in =================================================================== --- gcc/cp/Make-lang.in (revision 184772) +++ gcc/cp/Make-lang.in (working copy) @@ -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 Index: gcc/cp/pph.h =================================================================== --- gcc/cp/pph.h (revision 184772) +++ gcc/cp/pph.h (working copy) @@ -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. */ Index: gcc/cp/pph-out.c =================================================================== --- gcc/cp/pph-out.c (revision 184772) +++ gcc/cp/pph-out.c (working copy) @@ -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. */ Index: gcc/cp/pt.c =================================================================== --- gcc/cp/pt.c (revision 184772) +++ gcc/cp/pt.c (working copy) @@ -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); + } } Index: gcc/cp/mangle.c =================================================================== --- gcc/cp/mangle.c (revision 184772) +++ gcc/cp/mangle.c (working copy) @@ -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: Index: gcc/cp/pph-in.c =================================================================== --- gcc/cp/pph-in.c (revision 184772) +++ gcc/cp/pph-in.c (working copy) @@ -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. */ Index: gcc/strptrmap.c =================================================================== --- gcc/strptrmap.c (revision 0) +++ gcc/strptrmap.c (revision 0) @@ -0,0 +1,175 @@ +/* A string to string mapping. + + Copyright (C) 2012 Free Software Foundation, Inc. + Contributed by Lawrence Crowl . + + 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 +. */ + +#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; +} Index: gcc/strptrmap.h =================================================================== --- gcc/strptrmap.h (revision 0) +++ gcc/strptrmap.h (revision 0) @@ -0,0 +1,27 @@ +/* A string to string mapping. + + Copyright (C) 2012 Free Software Foundation, Inc. + Contributed by Lawrence Crowl . + + 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 +. */ + +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); Index: gcc/Makefile.in =================================================================== --- gcc/Makefile.in (revision 184772) +++ gcc/Makefile.in (working copy) @@ -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