summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-12-02 07:31:39 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-12-02 07:31:39 +0000
commit47c16a8cec2c48947e6d85683f5f916777ccc169 (patch)
tree3a8bf827ae1df7e637a2a4ede4dba5f0421ac0d2
parentb27941d363b11d115e30a9676e61c8536a12adf7 (diff)
downloadgcc-47c16a8cec2c48947e6d85683f5f916777ccc169.tar.gz
2009-12-02 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 154895 {after more plugin events from ICI folks} git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@154896 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog.MELT5
-rw-r--r--boehm-gc/ChangeLog6
-rw-r--r--boehm-gc/mark_rts.c8
-rw-r--r--config/ChangeLog5
-rw-r--r--config/largefile.m45
-rw-r--r--gcc/ChangeLog330
-rw-r--r--gcc/ChangeLog.graphite62
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in27
-rw-r--r--gcc/ada/ChangeLog801
-rw-r--r--gcc/ada/Makefile.rtl47
-rw-r--r--gcc/ada/a-calend.adb71
-rw-r--r--gcc/ada/a-cdlili.adb24
-rw-r--r--gcc/ada/a-clrefi.adb4
-rw-r--r--gcc/ada/a-clrefi.ads2
-rw-r--r--gcc/ada/a-coinve.adb45
-rw-r--r--gcc/ada/a-comlin.ads2
-rw-r--r--gcc/ada/a-crbtgo.adb27
-rw-r--r--gcc/ada/a-ioexce.ads2
-rw-r--r--gcc/ada/a-ngelfu.adb112
-rw-r--r--gcc/ada/a-rttiev.adb24
-rw-r--r--gcc/ada/a-strhas.ads2
-rw-r--r--gcc/ada/a-ststio.adb5
-rw-r--r--gcc/ada/a-tasatt.adb7
-rw-r--r--gcc/ada/a-textio.adb4
-rw-r--r--gcc/ada/a-tiinio.adb9
-rw-r--r--gcc/ada/a-wtinio.adb9
-rw-r--r--gcc/ada/a-ztinio.adb9
-rw-r--r--gcc/ada/adadecode.c31
-rw-r--r--gcc/ada/adaint.c32
-rw-r--r--gcc/ada/adaint.h14
-rw-r--r--gcc/ada/bcheck.adb1
-rw-r--r--gcc/ada/clean.adb1
-rw-r--r--gcc/ada/csinfo.adb11
-rw-r--r--gcc/ada/debug.adb6
-rw-r--r--gcc/ada/einfo.ads14
-rw-r--r--gcc/ada/errout.adb24
-rw-r--r--gcc/ada/exp_atag.adb129
-rw-r--r--gcc/ada/exp_atag.ads15
-rw-r--r--gcc/ada/exp_ch3.adb5
-rw-r--r--gcc/ada/exp_ch4.adb126
-rw-r--r--gcc/ada/exp_ch6.adb34
-rw-r--r--gcc/ada/exp_ch7.adb25
-rw-r--r--gcc/ada/exp_ch9.adb218
-rw-r--r--gcc/ada/exp_ch9.ads75
-rw-r--r--gcc/ada/exp_intr.adb35
-rw-r--r--gcc/ada/exp_util.adb41
-rw-r--r--gcc/ada/expect.c9
-rw-r--r--gcc/ada/freeze.adb35
-rw-r--r--gcc/ada/frontend.adb24
-rw-r--r--gcc/ada/g-alleve.adb205
-rw-r--r--gcc/ada/g-arrspl.adb4
-rw-r--r--gcc/ada/g-comlin.adb23
-rw-r--r--gcc/ada/g-comlin.ads3
-rw-r--r--gcc/ada/g-debpoo.adb13
-rw-r--r--gcc/ada/g-dirope.adb24
-rw-r--r--gcc/ada/g-dyntab.adb7
-rw-r--r--gcc/ada/g-dyntab.ads2
-rw-r--r--gcc/ada/g-enblsp-vms-alpha.adb10
-rw-r--r--gcc/ada/g-enblsp-vms-ia64.adb9
-rw-r--r--gcc/ada/g-exctra.adb14
-rw-r--r--gcc/ada/g-expect-vms.adb6
-rw-r--r--gcc/ada/g-expect.adb9
-rw-r--r--gcc/ada/g-htable.adb6
-rw-r--r--gcc/ada/g-md5.adb533
-rw-r--r--gcc/ada/g-md5.ads90
-rw-r--r--gcc/ada/g-pehage.adb15
-rw-r--r--gcc/ada/g-regist.adb6
-rw-r--r--gcc/ada/g-sercom-linux.adb22
-rw-r--r--gcc/ada/g-sercom-mingw.adb11
-rw-r--r--gcc/ada/g-sercom.ads6
-rw-r--r--gcc/ada/g-sha1.adb375
-rw-r--r--gcc/ada/g-sha1.ads101
-rw-r--r--gcc/ada/g-socket.adb50
-rw-r--r--gcc/ada/g-socket.ads22
-rw-r--r--gcc/ada/g-socthi-mingw.ads4
-rw-r--r--gcc/ada/g-socthi-vms.adb15
-rw-r--r--gcc/ada/g-socthi-vms.ads4
-rw-r--r--gcc/ada/g-socthi-vxworks.adb16
-rw-r--r--gcc/ada/g-socthi-vxworks.ads4
-rw-r--r--gcc/ada/g-socthi.adb15
-rw-r--r--gcc/ada/g-socthi.ads4
-rw-r--r--gcc/ada/g-sothco.ads51
-rw-r--r--gcc/ada/g-sttsne-locking.adb54
-rw-r--r--gcc/ada/g-trasym-vms-alpha.adb8
-rw-r--r--gcc/ada/gcc-interface/Make-lang.in409
-rw-r--r--gcc/ada/gcc-interface/Makefile.in69
-rw-r--r--gcc/ada/gcc-interface/trans.c1
-rw-r--r--gcc/ada/gnat1drv.adb15
-rw-r--r--gcc/ada/gnat_rm.texi185
-rw-r--r--gcc/ada/gnat_ugn.texi51
-rw-r--r--gcc/ada/gnatcmd.adb35
-rw-r--r--gcc/ada/gnatlink.adb84
-rw-r--r--gcc/ada/gnatls.adb3
-rw-r--r--gcc/ada/i-vxwoio.adb8
-rw-r--r--gcc/ada/impunit.adb4
-rw-r--r--gcc/ada/init.c8
-rw-r--r--gcc/ada/lib-writ.ads4
-rw-r--r--gcc/ada/make.adb244
-rw-r--r--gcc/ada/makeutl.adb74
-rw-r--r--gcc/ada/makeutl.ads69
-rw-r--r--gcc/ada/opt.adb8
-rw-r--r--gcc/ada/opt.ads24
-rw-r--r--gcc/ada/osint.adb219
-rw-r--r--gcc/ada/osint.ads87
-rw-r--r--gcc/ada/par-prag.adb6
-rw-r--r--gcc/ada/par_sco.adb7
-rw-r--r--gcc/ada/prj-attr.adb6
-rw-r--r--gcc/ada/prj-attr.ads14
-rw-r--r--gcc/ada/prj-conf.adb26
-rw-r--r--gcc/ada/prj-env.adb2
-rw-r--r--gcc/ada/prj-ext.adb6
-rw-r--r--gcc/ada/prj-makr.adb36
-rw-r--r--gcc/ada/prj-nmsc.adb161
-rw-r--r--gcc/ada/prj-part.adb2
-rw-r--r--gcc/ada/prj-pp.adb11
-rw-r--r--gcc/ada/prj-proc.adb50
-rw-r--r--gcc/ada/prj-tree.adb54
-rw-r--r--gcc/ada/prj-tree.ads120
-rw-r--r--gcc/ada/prj.adb80
-rw-r--r--gcc/ada/prj.ads257
-rw-r--r--gcc/ada/put_scos.adb25
-rw-r--r--gcc/ada/s-bitops.adb2
-rw-r--r--gcc/ada/s-crtl.ads30
-rw-r--r--gcc/ada/s-errrep.adb68
-rw-r--r--gcc/ada/s-errrep.ads45
-rw-r--r--gcc/ada/s-fatgen.adb7
-rw-r--r--gcc/ada/s-fileio.adb32
-rw-r--r--gcc/ada/s-imgcha.adb13
-rw-r--r--gcc/ada/s-oscons-tmplt.c40
-rw-r--r--gcc/ada/s-osinte-aix.ads4
-rw-r--r--gcc/ada/s-osinte-darwin.ads2
-rw-r--r--gcc/ada/s-osinte-freebsd.ads4
-rw-r--r--gcc/ada/s-osinte-hpux-dce.adb8
-rw-r--r--gcc/ada/s-osinte-hpux.ads4
-rw-r--r--gcc/ada/s-osinte-solaris-posix.ads4
-rw-r--r--gcc/ada/s-osinte-tru64.adb9
-rw-r--r--gcc/ada/s-osinte-tru64.ads4
-rw-r--r--gcc/ada/s-osprim-mingw.adb43
-rw-r--r--gcc/ada/s-parame.adb2
-rw-r--r--gcc/ada/s-parame.ads2
-rw-r--r--gcc/ada/s-restri.adb2
-rw-r--r--gcc/ada/s-restri.ads2
-rw-r--r--gcc/ada/s-stausa.adb20
-rw-r--r--gcc/ada/s-stchop-vxworks.adb17
-rw-r--r--gcc/ada/s-stchop.adb8
-rw-r--r--gcc/ada/s-strhas.adb2
-rw-r--r--gcc/ada/s-strxdr.adb36
-rw-r--r--gcc/ada/s-taenca.adb9
-rw-r--r--gcc/ada/s-taprop-dummy.adb6
-rw-r--r--gcc/ada/s-taprop-hpux-dce.adb75
-rw-r--r--gcc/ada/s-taprop-irix.adb70
-rw-r--r--gcc/ada/s-taprop-linux.adb76
-rw-r--r--gcc/ada/s-taprop-mingw.adb11
-rw-r--r--gcc/ada/s-taprop-posix.adb76
-rw-r--r--gcc/ada/s-taprop-solaris.adb19
-rw-r--r--gcc/ada/s-taprop-tru64.adb74
-rw-r--r--gcc/ada/s-taprop-vms.adb35
-rw-r--r--gcc/ada/s-taprop-vxworks.adb78
-rw-r--r--gcc/ada/s-tarest.adb18
-rw-r--r--gcc/ada/s-tassta.adb4
-rw-r--r--gcc/ada/s-vxwext.adb2
-rw-r--r--gcc/ada/s-vxwext.ads2
-rw-r--r--gcc/ada/scans.ads8
-rw-r--r--gcc/ada/scn.adb7
-rw-r--r--gcc/ada/scng.adb21
-rw-r--r--gcc/ada/scos.ads124
-rw-r--r--gcc/ada/sem.adb1
-rw-r--r--gcc/ada/sem_case.adb9
-rw-r--r--gcc/ada/sem_ch10.adb35
-rw-r--r--gcc/ada/sem_ch3.adb29
-rw-r--r--gcc/ada/sem_ch4.adb2
-rw-r--r--gcc/ada/sem_ch6.adb66
-rw-r--r--gcc/ada/sem_disp.adb43
-rw-r--r--gcc/ada/sem_prag.adb103
-rw-r--r--gcc/ada/sem_scil.adb56
-rw-r--r--gcc/ada/sem_util.adb81
-rw-r--r--gcc/ada/sem_util.ads100
-rw-r--r--gcc/ada/sem_warn.adb16
-rw-r--r--gcc/ada/sinfo.adb40
-rw-r--r--gcc/ada/sinfo.ads65
-rw-r--r--gcc/ada/snames.ads-tmpl6
-rw-r--r--gcc/ada/socket.c109
-rw-r--r--gcc/ada/sprint.adb8
-rw-r--r--gcc/ada/switch-m.ads3
-rw-r--r--gcc/ada/system-vxworks-ppc.ads2
-rw-r--r--gcc/ada/usage.adb23
-rw-r--r--gcc/ada/vms_data.ads12
-rw-r--r--gcc/ada/xoscons.adb60
-rw-r--r--gcc/cgraph.h16
-rw-r--r--gcc/cgraphunit.c7
-rw-r--r--gcc/config.in7
-rw-r--r--gcc/config/arm/arm.h2
-rw-r--r--gcc/config/i386/abmintrin.h70
-rw-r--r--gcc/config/i386/cygming.opt6
-rw-r--r--gcc/config/i386/cygwin.h32
-rw-r--r--gcc/config/i386/i386-builtin-types.def3
-rw-r--r--gcc/config/i386/i386-c.c2
-rw-r--r--gcc/config/i386/i386-protos.h2
-rw-r--r--gcc/config/i386/i386.c444
-rw-r--r--gcc/config/i386/i386.md11
-rw-r--r--gcc/config/i386/predicates.md31
-rw-r--r--gcc/config/i386/sse.md557
-rw-r--r--gcc/config/i386/winnt.c67
-rw-r--r--gcc/config/i386/x86intrin.h4
-rw-r--r--gcc/config/mips/mips-dsp.md2
-rw-r--r--gcc/config/sh/sh-protos.h2
-rw-r--r--gcc/config/sh/sh.c57
-rw-r--r--gcc/config/sh/sh.h32
-rw-r--r--gcc/config/stormy16/stormy16-lib2-count-leading-zeros.c2
-rw-r--r--gcc/config/stormy16/stormy16-lib2.c44
-rw-r--r--gcc/config/stormy16/t-stormy1610
-rwxr-xr-xgcc/configure26
-rw-r--r--gcc/configure.ac19
-rw-r--r--gcc/cp/ChangeLog34
-rw-r--r--gcc/cp/call.c19
-rw-r--r--gcc/cp/decl2.c4
-rw-r--r--gcc/cp/optimize.c68
-rw-r--r--gcc/cp/parser.c2
-rw-r--r--gcc/cp/pt.c7
-rw-r--r--gcc/cp/semantics.c3
-rw-r--r--gcc/doc/contrib.texi4
-rw-r--r--gcc/doc/plugins.texi63
-rw-r--r--gcc/expr.c5
-rw-r--r--gcc/final.c2
-rw-r--r--gcc/fortran/ChangeLog82
-rw-r--r--gcc/fortran/decl.c104
-rw-r--r--gcc/fortran/dump-parse-tree.c4
-rw-r--r--gcc/fortran/gfortran.h13
-rw-r--r--gcc/fortran/intrinsic.c2
-rw-r--r--gcc/fortran/intrinsic.h1
-rw-r--r--gcc/fortran/iresolve.c51
-rw-r--r--gcc/fortran/match.c19
-rw-r--r--gcc/fortran/module.c19
-rw-r--r--gcc/fortran/resolve.c226
-rw-r--r--gcc/fortran/symbol.c232
-rw-r--r--gcc/fortran/trans-decl.c2
-rw-r--r--gcc/fortran/trans-expr.c192
-rw-r--r--gcc/fortran/trans-intrinsic.c34
-rw-r--r--gcc/fortran/trans-stmt.c107
-rw-r--r--gcc/fortran/trans-types.c4
-rw-r--r--gcc/function.c8
-rw-r--r--gcc/gcc-plugin.h36
-rw-r--r--gcc/graphite-clast-to-gimple.c583
-rw-r--r--gcc/graphite-scop-detection.c20
-rw-r--r--gcc/graphite-sese-to-poly.c23
-rw-r--r--gcc/ipa-prop.c3
-rw-r--r--gcc/ipa-prop.h6
-rw-r--r--gcc/ipa-reference.c29
-rw-r--r--gcc/ipa-struct-reorg.c14
-rw-r--r--gcc/params.c10
-rw-r--r--gcc/params.h3
-rw-r--r--gcc/passes.c49
-rw-r--r--gcc/plugin.c190
-rw-r--r--gcc/plugin.h2
-rw-r--r--gcc/print-rtl.c5
-rw-r--r--gcc/print-tree.c35
-rw-r--r--gcc/sese.c8
-rw-r--r--gcc/sese.h107
-rw-r--r--gcc/testsuite/ChangeLog98
-rw-r--r--gcc/testsuite/g++.dg/abi/guard1.C10
-rw-r--r--gcc/testsuite/gcc.dg/graphite/pr35356-2.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/vperm-v4sf-1.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/regnames-1.c2
-rw-r--r--gcc/testsuite/gfortran.dg/class_4c.f031
-rw-r--r--gcc/testsuite/gfortran.dg/class_4d.f036
-rw-r--r--gcc/testsuite/gfortran.dg/module_md5_1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/same_type_as_1.f037
-rw-r--r--gcc/testsuite/gfortran.dg/select_type_1.f0310
-rw-r--r--gcc/testsuite/gfortran.dg/select_type_2.f0310
-rw-r--r--gcc/testsuite/lib/g++.exp7
-rw-r--r--gcc/testsuite/lib/gcc-dg.exp7
-rw-r--r--gcc/testsuite/lib/gfortran.exp7
-rw-r--r--gcc/testsuite/lib/objc.exp7
-rw-r--r--gcc/testsuite/lib/options.exp7
-rw-r--r--gcc/tree-cfgcleanup.c4
-rw-r--r--gcc/tree-dump.c1
-rw-r--r--gcc/tree-inline.c4
-rw-r--r--gcc/tree-into-ssa.c28
-rw-r--r--gcc/tree-optimize.c8
-rw-r--r--gcc/tree-pass.h8
-rw-r--r--gcc/tree-pretty-print.c23
-rw-r--r--gcc/tree-sra.c57
-rw-r--r--gcc/tree-ssa-live.c12
-rw-r--r--gcc/tree-vect-stmts.c43
-rw-r--r--gcc/tree.c2
-rw-r--r--libffi/ChangeLog29
-rw-r--r--libffi/src/powerpc/aix.S152
-rw-r--r--libffi/src/powerpc/aix_closure.S193
-rw-r--r--libffi/src/powerpc/ffi_darwin.c202
-rw-r--r--libffi/src/powerpc/ffitarget.h6
-rw-r--r--libgfortran/ChangeLog12
-rw-r--r--libgfortran/Makefile.am1
-rw-r--r--libgfortran/Makefile.in46
-rw-r--r--libgfortran/gfortran.map1
-rw-r--r--libgfortran/io/unix.c5
-rw-r--r--libgomp/ChangeLog5
-rw-r--r--libgomp/testsuite/lib/libgomp.exp7
-rw-r--r--libjava/ChangeLog10
-rw-r--r--libjava/java/net/natVMURLConnection.cc4
-rw-r--r--libjava/testsuite/lib/libjava.exp7
-rw-r--r--libstdc++-v3/ChangeLog55
-rw-r--r--libstdc++-v3/acinclude.m42
-rw-r--r--libstdc++-v3/config/os/mingw32/os_defines.h9
-rw-r--r--libstdc++-v3/config/os/newlib/os_defines.h9
-rwxr-xr-xlibstdc++-v3/configure2
-rw-r--r--libstdc++-v3/configure.host2
-rw-r--r--libstdc++-v3/include/Makefile.am1
-rw-r--r--libstdc++-v3/include/Makefile.in1
-rw-r--r--libstdc++-v3/include/bits/c++config10
-rw-r--r--libstdc++-v3/include/std/functional2161
-rw-r--r--libstdc++-v3/include/tr1/functional2110
-rw-r--r--libstdc++-v3/include/tr1_impl/functional2137
-rw-r--r--libstdc++-v3/testsuite/20_util/function/assign/move.cc50
-rw-r--r--libstdc++-v3/testsuite/20_util/function/cmp/cmp_neg.cc37
-rw-r--r--libstdc++-v3/testsuite/20_util/function/cons/move.cc48
-rw-r--r--libstdc++-v3/testsuite/20_util/function/invoke/move_only.cc61
-rw-r--r--libstdc++-v3/testsuite/lib/libstdc++.exp7
318 files changed, 13266 insertions, 7154 deletions
diff --git a/ChangeLog.MELT b/ChangeLog.MELT
index 07064b4319d..36ae3ca5e6f 100644
--- a/ChangeLog.MELT
+++ b/ChangeLog.MELT
@@ -1,7 +1,8 @@
-2009-11-30 Basile Starynkevitch <basile@starynkevitch.net>
+2009-12-02 Basile Starynkevitch <basile@starynkevitch.net>
- MELT branch merged with trunk rev 154755
+ MELT branch merged with trunk rev 154895
+ {after more plugin events from ICI folks}
2009-11-30 Basile Starynkevitch <basile@starynkevitch.net>
diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog
index 5b615d956a4..03e51589580 100644
--- a/boehm-gc/ChangeLog
+++ b/boehm-gc/ChangeLog
@@ -1,5 +1,11 @@
2009-11-30 Ben Elliston <bje@au.ibm.com>
+ * mark_rts.c (GC_approx_sp): Use __builtin_frame_address when
+ compiling with GCC rather than taking the address of a local
+ variable.
+
+2009-11-30 Ben Elliston <bje@au.ibm.com>
+
* os_dep.c: Use the POSIX signal API in preference to the BSD API.
Generate a compilation error if neither the POSIX nor BSD APIs can
be detected.
diff --git a/boehm-gc/mark_rts.c b/boehm-gc/mark_rts.c
index 4074879a71a..7a9fb8f2b72 100644
--- a/boehm-gc/mark_rts.c
+++ b/boehm-gc/mark_rts.c
@@ -376,7 +376,13 @@ ptr_t GC_approx_sp()
# ifdef _MSC_VER
# pragma warning(disable:4172)
# endif
- return((ptr_t)(&dummy));
+#ifdef __GNUC__
+ /* Eliminate a warning from GCC about taking the address of a
+ local variable. */
+ return __builtin_frame_address (0);
+#else
+ return ((ptr_t)(&dummy));
+#endif /* __GNUC__ */
# ifdef _MSC_VER
# pragma warning(default:4172)
# endif
diff --git a/config/ChangeLog b/config/ChangeLog
index aa716ea437d..9e524fc8737 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,8 @@
+2009-11-30 Joseph Myers <joseph@codesourcery.com>
+
+ * largefile.m4 (ACX_LARGEFILE): Require AC_CANONICAL_HOST and
+ AC_CANONICAL_TARGET.
+
2009-11-24 Joel Brobecker <brobecker@adacore.com>
* zlib.m4: New file.
diff --git a/config/largefile.m4 b/config/largefile.m4
index 9449b12dca4..4a88fd738fd 100644
--- a/config/largefile.m4
+++ b/config/largefile.m4
@@ -5,6 +5,11 @@
AC_DEFUN([ACX_LARGEFILE],[dnl
+# The tests for host and target for $enable_largefile require
+# canonical names.
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_CANONICAL_TARGET])
+
# As the $enable_largefile decision depends on --enable-plugins we must set it
# even in directories otherwise not depending on the $plugins option.
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ae70d025cb4..a28fc61680f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,315 @@
+2009-12-01 Sebastian Pop <sebastian.pop@amd.com>
+
+ * config/i386/abmintrin.h (__lzcnt16): New.
+ (__lzcnt): New.
+ (__lzcnt64): New.
+ * config/i386/i386-builtin-types.def (UINT16_FTYPE_UINT16): New.
+ * config/i386/i386.c (IX86_BUILTIN_CLZS): New.
+ (bdesc_special_args): Add __builtin_clzs.
+ (ix86_expand_args_builtin): Handle UINT16_FTYPE_UINT16.
+
+2009-12-01 Sebastian Pop <sebastian.pop@amd.com>
+
+ * config/i386/abmintrin.h (_mm_popcnt_u32): New.
+ (_mm_popcnt_u64): New.
+
+2009-12-01 Sebastian Pop <sebastian.pop@amd.com>
+
+ * config/i386/abmintrin.h: New.
+ * config/i386/i386-c.c (ix86_target_macros_internal): Defined __ABM__.
+ * config/i386/x86intrin.h: Include abmintrin.h when __ABM__ is defined.
+
+2009-12-01 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (SWI124): Rename from CRC32MODE.
+ (crc32modesuffix): Remove.
+ (crc32modeconstraint): Ditto.
+ (sse4_2_crc32<mode>): Update for renamed mode iterator. Use
+ imodesuffix instead of crc32modesuffix and <r>m instead of
+ crc32modeconstraint.
+
+2009-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/42234
+ * tree-cfgcleanup.c (cleanup_omp_return): Don't ICE if control_bb
+ contains no statements.
+
+2009-12-01 Grigori Fursin <grigori.fursin@inria.fr>
+ Joern Rennecke <amylaar@spamcop.net>
+
+ * cgraphunit.c (plugin.h): Include.
+ (ipa_passes): Invoke PLUGIN_ALL_IPA_PASSES_START /
+ PLUGIN_ALL_IPA_PASSES_END at start / end of processing.
+ * gcc-plugin.h (highlev-plugin-common.h, hashtab.h): Include.
+ (enum plugin_event): Define by including plugin.def.
+ Last enumerator is now called PLUGIN_EVENT_FIRST_DYNAMIC.
+ (plugin_event_name): Change type to const char **.
+ (get_event_last, get_named_event_id, unregister_callback): Declare.
+ (register_callback): Change type of event argument to int.
+ (highlev-plugin-common.h): New file.
+ * Makefile.in (GCC_PLUGIN_H): Add highlev-plugin-common.h and
+ $(HASHTAB_H)
+ (tree-optimize.o passes.o): Depend on $(PLUGIN_H).
+ (PLUGIN_HEADERS): Add opts.h, $(PARAMS_H) and plugin.def.
+ (s-header-vars): New rule.
+ (install-plugin): Depend on s-header-vars. Install b-header-vars.
+ * params.c (get_num_compiler_params): New function.
+ * params.h (get_num_compiler_params): Declare.
+ * passes.c (plugin.h): Include.
+ (make_pass_instance): Invoke PLUGIN_NEW_PASS.
+ (do_per_function_toporder, pass_init_dump_file): No longer static.
+ (pass_fini_dump_file): Likewise.
+ (execute_one_pass): Likewise. Invoke PLUGIN_OVERRIDE_GATE and
+ PLUGIN_PASS_EXECUTION.
+ (execute_ipa_pass_list): Invoke PLUGIN_EARLY_GIMPLE_PASSES_START and
+ PLUGIN_EARLY_GIMPLE_PASSES_END.
+ * plugin.c (plugin_event_name_init): New array, defined by
+ including plugin.def.
+ (FMT_FOR_PLUGIN_EVENT): Update.
+ (plugin_event_name): Change type to const char ** and initialize
+ to plugin_event_name_init.
+ (event_tab, event_last, event_horizon): New variable.
+ (get_event_last): New function.
+ (plugin_callbacks_init): New array.
+ (plugin_callbacks: Change type to struct callback_info **.
+ Initialize to plugin_callbacks_init.
+ (htab_event_eq, get_named_event_id, unregister_callback): New function.
+ (invoke_plugin_va_callbacks): Likewise.
+ (register_callback): Change type of event argument to int.
+ Handle new events. Allow dynamic events.
+ (invoke_plugin_callbacks): Likewise. Return success status.
+ (plugins_active_p): Allow dynamic callbacks.
+ * plugin.def: New file.
+ * plugin.h (invoke_plugin_callbacks): Update prototype.
+ (invoke_plugin_va_callbacks): Declare.
+ * tree-optimize.c (plugin.h): Include.
+ (tree_rest_of_compilation): Invoke PLUGIN_ALL_PASSES_START and
+ PLUGIN_ALL_PASSES_END.
+ * tree-pass.h (execute_one_pass, pass_init_dump_file): Declare.
+ (pass_fini_dump_file, do_per_function_toporder): Likewise.
+ * doc/plugin.texi: Document new event types.
+
+2009-12-01 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/42237
+ * tree-sra.c (sra_ipa_modify_assign): Split gimple_reg_type assignments
+ in between references into two.
+
+2009-12-01 Richard Guenther <rguenther@suse.de>
+
+ * tree-inline.c (copy_tree_body_r): Do not set TREE_BLOCK
+ to the block of the call when remapping a type.
+
+2009-12-01 Martin Jambor <mjambor@suse.cz>
+
+ * cgraph.h (struct cgraph_edge): Reorder fields. Make loop_nest
+ unsigned short int.
+ * ipa-prop.h (struct ipa_param_call_note): Likewise.
+ * ipa-prop.c (ipa_note_param_call): Initialize note->loop_nest.
+
+2009-12-01 Richard Guenther <rguenther@suse.de>
+
+ * final.c (rest_of_clean_state): If -fcompare-debug is
+ given dump final insns without UIDs.
+ * tree-ssa-live.c (remove_unused_scope_block_p): Remove
+ after_inlining checks.
+
+2009-11-30 Chao-ying Fu <fu@mips.com>
+
+ * config/mips/mips-dsp.md (mips_lhx_<mode>): Use sign_extend.
+
+2009-11-30 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * configure.ac (USE_CYGWIN_LIBSTDCXX_WRAPPERS): Define to reflect
+ status of AC_CHECK_FUNC for Cygwin DLL libstdc++ support wrappers.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+
+ * config/i386/cygwin.h (CXX_WRAP_SPEC_LIST): Define list of --wrap
+ options for Cygwin DLL libstdc++ support wrappers.
+ (CXX_WRAP_SPEC_OPT): Define spec to use wrappers or not by default
+ according to defined value of USE_CYGWIN_LIBSTDCXX_WRAPPERS.
+ (CXX_WRAP_SPEC): Define entire wrapper spec in or out according to
+ whether USE_CYGWIN_LIBSTDCXX_WRAPPERS is even defined or not.
+ (LINK_SPEC): Include CXX_WRAP_SPEC.
+ * gcc/config/i386/winnt.c (wrapper_strcmp): New qsort helper function.
+ (i386_find_on_wrapper_list): Check if a function is found on the list
+ of libstdc++ wrapper options.
+ (i386_pe_file_end): If we are importing a wrapped function, also emit
+ an external declaration for the real version.
+ * config/i386/cygming.opt (muse-libstdc-wrappers): New option for
+ Cygwin targets. Update copyright year.
+
+2009-11-30 Steve Ellcey <sje@cup.hp.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * function.c (instantiate_virtual_regs_in_insn): Copy to new reg
+ before forcing mode.
+
+2009-11-30 Anatoly Sokolov <aesok@post.ru>
+
+ * config/sh/sh.c (sh_promote_prototypes): Make static.
+ (sh_function_value, sh_libcall_value, sh_function_value_regno_p): New
+ functions.
+ (TARGET_FUNCTION_VALUE, TARGET_LIBCALL_VALUE): Declare.
+ * config/sh/sh.h: (FUNCTION_VALUE_REGNO_P): Redefine, use
+ sh_function_value_regno_p.
+ (FUNCTION_VALUE, LIBCALL_VALUE): Remove.
+ * config/sh/sh-protos.h (sh_function_value_regno_p): Declare.
+ (sh_promote_prototypes) : Remove.
+
+2009-11-30 Julian Brown <julian@codesourcery.com>
+
+ * config/arm/arm.h (PREFERRED_RELOAD_CLASS): Don't restrict Thumb-2
+ reloads to LO_REGS.
+
+2009-11-30 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (ix86_vec_interleave_v2df_operator_ok): New.
+ (bdesc_special_args): Update insn codes.
+ (avx_vpermilp_parallel): Correct range check.
+ (ix86_rtx_costs): Handle vector permutation rtx codes.
+ (struct expand_vec_perm_d): Move earlier.
+ (get_mode_wider_vector): New.
+ (expand_vec_perm_broadcast_1): New.
+ (ix86_expand_vector_init_duplicate): Use it. Tidy AVX modes.
+ (expand_vec_perm_broadcast): New.
+ (ix86_expand_vec_perm_builtin_1): Use it.
+ * config/i386/i386-protos.h: Update.
+ * config/i386/predicates.md (avx_vbroadcast_operand): New.
+ * config/i386/sse.md (AVX256MODE24P): New.
+ (ssescalarmodesuffix2s): New.
+ (avxhalfvecmode, avxscalarmode): Fill out to all modes.
+ (avxmodesuffixf2c): Add V8SI, V4DI.
+ (vec_dupv4sf): New expander.
+ (*vec_dupv4sf_avx): Add vbroadcastss alternative.
+ (*vec_set<mode>_0_avx, **vec_set<mode>_0_sse4_1): Macro-ize for
+ V4SF and V4SI. Move C alternatives to front. Add insertps and
+ pinsrd alternatives.
+ (*vec_set<mode>_0_sse2): Split out from ...
+ (vec_set<mode>_0): Macro-ize for V4SF and V4SI.
+ (vec_interleave_highv2df, vec_interleave_lowv2df): Require register
+ destination; use ix86_vec_interleave_v2df_operator_ok, instead of
+ ix86_fixup_binary_operands.
+ (*avx_interleave_highv2df, avx_interleave_lowv2df): Add movddup.
+ (*sse3_interleave_highv2df, sse3_interleave_lowv2df): New.
+ (*avx_movddup, *sse3_movddup): Remove. New splitter from
+ vec_select form to vec_duplicate form.
+ (*sse2_interleave_highv2df, sse2_interleave_lowv2df): Use
+ ix86_vec_interleave_v2df_operator_ok.
+ (avx_movddup256, avx_unpcklpd256): Change to expanders, merge into ...
+ (*avx_unpcklpd256): ... here.
+ (*vec_dupv4si_avx): New.
+ (*vec_dupv2di_avx): Add movddup alternative.
+ (*vec_dupv2di_sse3): New.
+ (vec_dup<AVX256MODE24P>): Replace avx_vbroadcasts<AVXMODEF4P> and
+ avx_vbroadcastss256; represent with vec_duplicate instead of
+ nested vec_concat operations.
+ (avx_vbroadcastf128_<mode>): Rename from
+ avx_vbroadcastf128_p<avxmodesuffixf2c>256.
+ (*avx_vperm_broadcast_v4sf): New.
+ (*avx_vperm_broadcast_<AVX256MODEF2P>): New.
+
+2009-11-30 Martin Jambor <mjambor@suse.cz>
+
+ PR middle-end/42196
+ * tree-sra.c (struct access): New field grp_different_types.
+ (dump_access): Dump grp_different_types.
+ (compare_access_positions): Prefer scalars and vectors over other
+ scalar types.
+ (sort_and_splice_var_accesses): Set grp_different_types if appropriate.
+ (sra_modify_expr): Use the original also when dealing with a complex
+ or vector group accessed as multiple types.
+
+2009-11-30 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (avx_vperm2f128_parallel): New.
+ * config/i386/i386-protos.h: Declare it.
+ * config/i386/predicates.md (avx_vperm2f128_v8sf_operand,
+ avx_vperm2f128_v8si_operand, avx_vperm2f128_v4df_operand): New.
+ * config/i386/sse.md (avx_vperm2f128<mode>3): Change to expander.
+ (*avx_vperm2f128<mode>_full): Renamed from avx_vperm2f128<mode>3.
+ (*avx_vperm2f128<mode>_nozero): New.
+
+2009-11-30 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386-builtin-types.def (V4DF_FTYPE_V4DF_V4DF_V4DI): New.
+ (V8SF_FTYPE_V8SF_V8SF_V8SI): New.
+ * config/i386/i386.c (ix86_vectorize_builtin_vec_perm): Support
+ V4DF and V8SF for AVX; relax constraint on V4SF to SSE1 from SSE2.
+ (IX86_BUILTIN_VEC_PERM_V4DF, IX86_BUILTIN_VEC_PERM_V8SF): New.
+ (bdesc_args): Add them.
+ (ix86_expand_builtin): Expand them.
+ (expand_vec_perm_pshufb2): Only operate on 16-byte vectors.
+
+2009-11-30 Martin Jambor <mjambor@suse.cz>
+
+ PR middle-end/42206
+ * ipa-prop.c (ipa_write_node_info): Initialize note_count to zero.
+
+2009-11-30 Jakub Jelinek <jakub@redhat.com>
+
+ * ipa-reference.c (propagate): Only dump bitmaps if computed.
+
+2009-11-30 Olga Golovanevsky <olga@il.ibm.com>
+
+ PR middle-end/39806
+ * ipa-struct-reorg.c (new_var_eq): Use DECL_UID to hash new variables.
+ (new_var_hash): Likewise.
+ (is_in_new_vars_htab): Likewise.
+ (add_to_new_vars_htab): Likewise.
+
+2009-11-30 Ira Rosen <irar@il.ibm.com>
+
+ * tree-vect-stmts.c (vectorizable_assignment): Support
+ multiple types.
+
+2009-11-30 Richard Guenther <rguenther@suse.de>
+
+ * doc/contrib.texi (Contributors): Add myself.
+
+2009-11-30 Richard Guenther <rguenther@suse.de>
+
+ * tree.c (free_lang_data): Do not set debug_info_level to
+ none if terse.
+
+2009-11-30 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/42119
+ PR fortran/38530
+ * expr.c (expand_expr_addr_expr_1): Properly expand the initializer
+ of CONST_DECLs.
+
+2009-11-30 Richard Guenther <rguenther@suse.de>
+
+ * tree-into-ssa.c (insert_phi_nodes): Add PHI nodes in
+ variable UID order.
+
+2009-11-30 Richard Guenther <rguenther@suse.de>
+
+ * tree-dump.c (dump_option_value_in): Add TDF_NOUID.
+ * tree-pass.h (TDF_NOUID): Likewise.
+ * print-rtl.c: Include tree-pass.h.
+ (print_mem_expr): Pass dump_flags.
+ (print_rtx): Likewise.
+ * print-tree.c: Include tree-pass.h.
+ (print_node_brief): Handle TDF_NOUID.
+ (print_node): Likewise.
+ * tree-pretty-print.c (dump_decl_name): Likewise.
+ (dump_generic_node): Likewise.
+ * Makefile.in (print-rtl.o, print-tree.o): Add $(TREE_PASS_H)
+ dependency.
+
+2009-11-30 Nick Clifton <nickc@redhat.com>
+
+ * config/stormy16/stormy16-lib2-count-leading-zeros.c: Delete.
+ * config/stormy16/t-stormy16 (LIB2FUNCS_EXTRA): Remove
+ stormy16-lib2-count-leading-zeros.c.
+ * config/stormy16/stormy16-lib2.c (__clzhi2): Move code from
+ __stormy16_count_leading_zeros() into this function.
+ (__ctzhi2): Use __builtin_clz.
+ (__ffshi2): Likewise.
+
2009-11-30 Eric Botcazou <ebotcazou@adacore.com>
* config/sparc/sparc.c (DF_MODES): Simplify.
@@ -63,7 +375,8 @@
(cgraph_expand_function): Handle thunks.
(thunk_adjust): New.
(init_lowered_empty_function): New.
- * cp-objcp-common.h (LANG_HOOKS_CALLGRAPH_EMIT_ASSOCIATED_THUNKS): Remove.
+ * cp-objcp-common.h (LANG_HOOKS_CALLGRAPH_EMIT_ASSOCIATED_THUNKS):
+ Remove.
* lto-cgraph.c (lto_output_node): Stream thunk info.
(input_node): Likewise.
* langhooks.h (lang_hooks_for_callgraph): Remove emit_associated_thunks.
@@ -177,7 +490,7 @@
2009-11-28 Andy Hutchinson <hutchinsonandy@gcc.gnu.org>
- * config/avr/avr.h (ASM_OUTPUT_EXTERNAL): Add.
+ * config/avr/avr.h (ASM_OUTPUT_EXTERNAL): Add.
2009-11-28 David Binderman <dcb314@hotmail.com>
@@ -197,9 +510,8 @@
2009-11-27 Nick Clifton <nickc@redhat.com>
- * longlong.h (count_leading_zeros): Define macro for stormy16
- target.
- (COUNT_LEADING_ZEROS_0): Likewise.
+ * longlong.h (count_leading_zeros): Define macro for stormy16 target.
+ (COUNT_LEADING_ZEROS_0): Likewise.
* config/stormy16/stormy16-lib2.c: Arrange for separate
compilation of each function.
(__ffshi2): New function.
@@ -251,8 +563,7 @@
[SUPPORTS_WEAK && GTHREAD_USE_WEAK] (__gthread_active_p): Use
__extension__ to allow cast from function pointer to object
pointer in C++.
- * doc/install.texi (--enable-threads): Clarify use of Solaris
- threads.
+ * doc/install.texi (--enable-threads): Clarify use of Solaris threads.
2009-11-27 Steven Bosscher <steven@gcc.gnu.org>
@@ -291,8 +602,7 @@
2009-11-27 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
- * emit-rtl.c (next_active_insn, prev_active_insn): Correct
- comment.
+ * emit-rtl.c (next_active_insn, prev_active_insn): Correct comment.
2009-11-27 Jakub Jelinek <jakub@redhat.com>
@@ -499,7 +809,7 @@
(struct builtin_description) <CODE_FOR_avx_vzeroupper_rex64>:
Remove initailization.
<CODE_FOR_avx_vzeroupper>: Unconditionally initialize here.
-
+
2009-11-25 Paul Brook <paul@codesourcery.com>
* config/arm/arm.md (consttable_4): Handle (high ...).
diff --git a/gcc/ChangeLog.graphite b/gcc/ChangeLog.graphite
index 53ffd9359cd..3ae20755abf 100644
--- a/gcc/ChangeLog.graphite
+++ b/gcc/ChangeLog.graphite
@@ -1,3 +1,65 @@
+2009-11-29 Alexander Monakov <amonakov@gcc.gnu.org>
+
+ * testsuite/g++.dg/graphite/pr42130.C: Correct testcase.
+
+2009-11-24 Tobias Grosser <grosser@fim.uni-passau.de>
+
+ * graphite-clast-to-gimple.c (try_mark_loop_parallel,
+ graphite_create_new_loop_guard, translate_clast_for): Fix comments.
+
+2009-11-23 Tobias Grosser <grosser@fim.uni-passau.de>
+
+ PR middle-end/42130
+ * graphite-clast-to-gimple.c (graphite_create_new_loop_guard,
+ translate_clast_for_loop): New.
+ (translate_clast_for): Add a condition around the loop, to do not
+ execute loops with zero iterations.
+ * testsuite/g++.dg/graphite/pr42130.C: New.
+ * testsuite/gcc.dg/graphite/pr35356-2.c: Adapt.
+
+2009-11-23 Tobias Grosser <grosser@fim.uni-passau.de>
+
+ * graphite-clast-to-gimple.c (try_mark_loop_parallel): New.
+ (translate_clast_for, translate_clast_guard, translate_clast, gloog):
+ Remove context_loop and level.
+
+2009-11-23 Tobias Grosser <grosser@fim.uni-passau.de>
+
+ * graphite-clast-to-gimple.c (translate_clast_user,
+ translate_clast_for, translate_clast_guard): Simplify and move common
+ elements to translate_clast().
+ (translate_clast): Simplify and get common elements.
+
+2009-11-23 Tobias Grosser <grosser@fim.uni-passau.de>
+
+ * graphite-clast-to-gimple.c (translate_clast_user,
+ translate_clast_for, translate_clast_guard): Split out of
+ translate_clast.
+
+2009-11-21 Tobias Grosser <grosser@fim.uni-passau.de>
+
+ * graphite-clast-to-gimple.c (clast_name_index, new_clast_name_index,
+ clast_name_to_index, save_clast_name_index, debug_clast_name_index,
+ debug_clast_name_indexes_1, debug_clast_name_indexes,
+ clast_name_index_elt_info, eq_clast_name_indexes): Moved from sese.h.
+ (clast_name_to_gcc, clast_to_gcc_expression,
+ clast_to_gcc_expression_red, gcc_type_for_clast_expr,
+ gcc_type_for_clast_eq, graphite_translate_clast_equation,
+ graphite_create_guard_cond_expr, graphite_create_new_loop,
+ translate_clast): Add params_index.
+ (initialize_cloog_names): Create parameter strings from scratch, do
+ not reference other strings.
+ (create_params_index): New.
+ (gloog): Initialize params_index.
+ * graphite-scop-detection (free_scops_1): Removed.
+ (limit_scops): Use normal free_scops.
+ * graphite-sese-to-poly.c (save_var_names): Removed.
+ (parameter_index_in_region): Do not initialize SESE_PARAM_NAMES
+ and SESE_PARAMS_INDEX.
+ * sese.c (new_sese, free_sese): Dito.
+ * sese.h (struct sese): Remove params_index, params_names.
+ (SESE_PARAMS_INDEX, SESE_PARAMS_NAMES): Removed.
+
2009-11-20 Sebastian Pop <sebastian.pop@amd.com>
Revert the following patch from 2009-09-14:
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index a41965d584c..e1c821eb5f4 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20091130
+20091202
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 80ed24b278c..a46860f0276 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -954,7 +954,8 @@ TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H)
IPA_PROP_H = ipa-prop.h $(TREE_H) vec.h $(CGRAPH_H)
GSTAB_H = gstab.h stab.def
BITMAP_H = bitmap.h $(HASHTAB_H) statistics.h
-GCC_PLUGIN_H = gcc-plugin.h $(CONFIG_H) $(SYSTEM_H)
+GCC_PLUGIN_H = gcc-plugin.h highlev-plugin-common.h $(CONFIG_H) $(SYSTEM_H) \
+ $(HASHTAB_H)
PLUGIN_H = plugin.h $(GCC_PLUGIN_H)
PLUGIN_VERSION_H = plugin-version.h configargs.h
@@ -2287,7 +2288,7 @@ tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(IPA_PROP_H) value-prof.h $(TREE_PASS_H) $(TARGET_H) $(INTEGRATE_H)
print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(GGC_H) langhooks.h $(REAL_H) tree-iterator.h fixed-value.h \
- $(DIAGNOSTIC_H) $(TREE_FLOW_H)
+ $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_PASS_H)
stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(PARAMS_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) output.h $(RTL_H) \
$(GGC_H) $(TM_P_H) $(TARGET_H) langhooks.h $(REGS_H) gt-stor-layout.h \
@@ -2526,8 +2527,9 @@ tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
langhooks.h alloc-pool.h pointer-set.h $(CFGLOOP_H)
tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) hard-reg-set.h $(EXPR_H) $(GGC_H) output.h \
- $(DIAGNOSTIC_H) $(BASIC_BLOCK_H) $(FLAGS_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
- $(TREE_DUMP_H) $(TOPLEV_H) $(FUNCTION_H) langhooks.h $(FLAGS_H) $(CGRAPH_H) \
+ $(DIAGNOSTIC_H) $(BASIC_BLOCK_H) $(FLAGS_H) $(TIMEVAR_H) $(TM_H) \
+ coretypes.h $(TREE_DUMP_H) $(TOPLEV_H) $(FUNCTION_H) langhooks.h \
+ $(FLAGS_H) $(CGRAPH_H) $(PLUGIN_H) \
$(TREE_INLINE_H) tree-mudflap.h $(GGC_H) graph.h $(CGRAPH_H) \
$(TREE_PASS_H) $(CFGLOOP_H) $(EXCEPT_H)
@@ -2768,7 +2770,8 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
langhooks.h insn-flags.h $(CFGLAYOUT_H) $(REAL_H) $(CFGLOOP_H) \
hosthooks.h $(CGRAPH_H) $(COVERAGE_H) $(TREE_PASS_H) $(TREE_DUMP_H) \
$(GGC_H) $(INTEGRATE_H) $(CPPLIB_H) opts.h $(TREE_FLOW_H) $(TREE_INLINE_H) \
- gt-passes.h $(DF_H) $(PREDICT_H) $(LTO_HEADER_H) $(LTO_SECTION_OUT_H)
+ gt-passes.h $(DF_H) $(PREDICT_H) $(LTO_HEADER_H) $(LTO_SECTION_OUT_H) \
+ $(PLUGIN_H)
plugin.o : plugin.c $(PLUGIN_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TOPLEV_H) $(TREE_H) $(TREE_PASS_H) intl.h $(PLUGIN_VERSION_H) $(GGC_H)
@@ -2787,7 +2790,7 @@ rtl.o : rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) $(FLAGS_H) \
- $(BCONFIG_H) $(REAL_H) $(DIAGNOSTIC_H) cselib.h
+ $(BCONFIG_H) $(REAL_H) $(DIAGNOSTIC_H) cselib.h $(TREE_PASS_H)
rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \
$(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) $(REAL_H) \
$(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H) $(TREE_H) \
@@ -4333,7 +4336,7 @@ installdirs:
PLUGIN_HEADERS = $(TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TOPLEV_H) $(BASIC_BLOCK_H) $(GIMPLE_H) $(TREE_PASS_H) $(GCC_PLUGIN_H) \
- $(GGC_H) $(TREE_DUMP_H) $(PRETTY_PRINT_H) \
+ $(GGC_H) $(TREE_DUMP_H) $(PRETTY_PRINT_H) opts.h $(PARAMS_H) plugin.def \
$(tm_file_list) $(tm_include_list) $(tm_p_file_list) $(tm_p_include_list) \
$(host_xm_file_list) $(host_xm_include_list) $(xm_include_list) \
intl.h $(PLUGIN_VERSION_H) $(DIAGNOSTIC_H) $(C_COMMON_H) $(C_PRETTY_PRINT_H) \
@@ -4345,8 +4348,15 @@ PLUGIN_HEADERS = $(TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
## extra MELT required plugin headers!
MELT_PLUGIN_HEADERS= melt-runtime.h run-melt.h melt-predef.h
+# generate the 'build fragment' b-header-vars
+s-header-vars: Makefile
+ rm -f tmp-header-vars
+ $(foreach header_var,$(shell sed < Makefile -e 's/^\([A-Z0-9_]*_H\)[ ]*=.*/\1/p' -e d),echo $(header_var)=$(shell echo $($(header_var):$(srcdir)/%=.../%) | sed -e 's~\.\.\./config/~config/~' -e 's~\.\.\..*/~~') >> tmp-header-vars;) \
+ $(SHELL) $(srcdir)/../move-if-change tmp-header-vars b-header-vars
+ $(STAMP) s-header-vars
+
# Install the headers needed to build a plugin.
-install-plugin: installdirs lang.install-plugin
+install-plugin: installdirs lang.install-plugin s-header-vars
# We keep the directory structure for files in config and .def files. All
# other files are flattened to a single directory.
$(mkinstalldirs) $(DESTDIR)$(plugin_includedir)
@@ -4370,6 +4380,7 @@ install-plugin: installdirs lang.install-plugin
$(mkinstalldirs) $(DESTDIR)$$dir; \
$(INSTALL_DATA) $$path $(DESTDIR)$$dest; \
done
+ $(INSTALL_DATA) b-header-vars $(DESTDIR)$(plugin_includedir)/b-header-vars
# Install the compiler executables built during cross compilation.
install-common: native lang.install-common installdirs
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 298dda24736..4c928457077 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,804 @@
+2009-12-01 Pascal Obry <obry@adacore.com>
+
+ * s-osprim-mingw.adb (Get_Base_Time): Make sure that the base time is
+ taken at a clock tick boundary.
+
+2009-12-01 Thomas Quinot <quinot@adacore.com>
+
+ * g-sechas.ads (GNAT.Secure_Hashes.H."=" on Context): Make abstract.
+
+2009-12-01 Matthew Gingell <gingell@adacore.com>
+
+ * adadecode.c: Allow compilation when building the run time in the gnat
+ runtime.
+ (__gnat_decode): Strip the .nnnn suffix from names of nested functions.
+
+ * gcc-interface/Makefile.in: Ada adadecode to LIBGNAT_SRCS and
+ LIBGNAT_OBJS.
+
+2009-12-01 Vincent Celier <celier@adacore.com>
+
+ * gnatcmd.adb (Check_Files): Quote the path names as they may include
+ spaces.
+
+2009-12-01 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch3.adb (Analyze_Object_Declaration): If the defining identifier
+ has already been declared, it may have been rewritten as a renaming
+ declaration.
+
+2009-12-01 Ed Schonberg <schonberg@adacore.com>
+
+ * einfo.ads: Clarify use of Is_Private_Primitive.
+ * sem_ch6.adb (Analyze_Subprogram_Declaration): An operation is a
+ private primitive operation only if it is declared in the scope of the
+ private controlling type.
+ * exp_ch9.adb (Build_Wrapper_Spec): Build wrappers for private
+ protected operations as well.
+
+2009-12-01 Arnaud Charlet <charlet@adacore.com>
+
+ * gnat1drv.adb (Adjust_Global_Switches): Disable front-end
+ optimizations in CodePeer mode, to keep the tree as close to the source
+ code as possible, and also to avoid inconsistencies between trees when
+ using different optimization switches.
+
+2009-12-01 Thomas Quinot <quinot@adacore.com>
+
+ * scos.ads: Updated specification of source coverage obligation
+ information.
+
+2009-12-01 Thomas Quinot <quinot@adacore.com>
+
+ * g-sercom.ads, g-sercom-mingw.adb, g-sercom-linux.adb,
+ a-ststio.adb, s-commun.adb, s-commun.ads, g-socket.adb,
+ g-socket.ads (System.Communications.Last_Index): For the case where no
+ element has been transferred and Item'First =
+ Stream_Element_Offset'First, raise CONSTRAINT_ERROR.
+
+2009-12-01 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch10.adb (Install_Siblings): A private with_clause on some child
+ unit U in an ancestor of the current unit must be ignored if the
+ current unit has a regular with_clause on U.
+
+2009-11-30 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * s-oscons-tmplt.c [__mips && __sgi]: Only define _XOPEN5, IOV_MAX
+ if _XOPEN_IOV_MAX is defined.
+
+2009-11-30 Vasiliy Fofanov <fofanov@adacore.com>
+
+ * vms_data.ads: Add new VMS qualifiers,
+ REVERSE_BIT_ORDER/NOREVERSE_BIT_ORDER, to support warnings on bit order
+ effects.
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * exp_ch9.adb, exp_ch9.ads, sem_util.ads: Minor reformatting.
+
+2009-11-30 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_prag.adb: Fix spelling error.
+
+2009-11-30 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch9.ads (Build_Private_Protected_Declaration): For a protected
+ operation that is only declared in a protected body, create a
+ corresponding subprogram declaration.
+ * exp_ch9.adb (Expand_N_Protected_Body): Create protected body of
+ operation in all cases, including for an operation that is only
+ declared in the body.
+ * sem_ch6.adb: Call Build_Private_Protected_Declaration
+ * exp_ch6.adb (Expand_N_Subprogram_Declaration): For an operation
+ declared in a protected body, create the declaration for the
+ corresponding protected version of the operation.
+
+2009-11-30 Arnaud Charlet <charlet@adacore.com>
+
+ * gnat1drv.adb (Adjust_Global_Switches): Disable specific expansions
+ for Restrictions pragmas, to avoid tree inconsistencies between
+ compilations with different pragmas.
+
+2009-11-30 Jerome Lambourg <lambourg@adacore.com>
+
+ * sem_prag.adb (Check_Duplicated_Export_Name): Allow entities exported
+ to CIL to have duplicated export name.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * a-tiinio.adb: Remove extraneous pragma Warnings (Off).
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * par_sco.adb: Minor reformatting
+
+2009-11-30 Ed Falis <falis@adacore.com>
+
+ * s-vxwext.ad[s,b], system-vxworks-ppc.ads, s-stchop-vxworks.adb:
+ Comment update.
+
+2009-11-30 Ed Schonberg <schonberg@adacore.com>
+
+ * par_sco.adb (Traverse_Handled_Statement_Sequence): Do not emit SCO's
+ for null statements that do not come from source.
+ * sinfo.ads: Clarify documentation of Comes_From_Source
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * prj-nmsc.adb (Add_Source): Use Display_Name for both projects when
+ displaying the paths in error message.
+
+2009-11-30 Emmanuel Briot <briot@adacore.com>
+
+ * adaint.h, adaint.c (file_attributes): force the use of unsigned char.
+ On some platforms, "char" is signed, on others unsigned, so we
+ explicitly specify the one we expect
+
+2009-11-30 Matthew Heaney <heaney@adacore.com>
+
+ * a-coinve.adb (Insert): Move exception handler closer to point where
+ exception can occur.
+ Minor reformatting & comment additions.
+
+2009-11-30 Arnaud Charlet <charlet@adacore.com>
+
+ * freeze.adb (Freeze_Entity): Disable warning on 'Foreign caller must
+ pass bounds' for VM targets, not relevant.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * sem_util.adb (Wrong_Type): Diagnose additional case of modular
+ missing parens.
+ * a-tiinio.adb, a-wtinio.adb, a-ztinio.adb: Minor reformatting
+
+ * exp_util.adb (Kill_Dead_Code): Suppress warning for some additional
+ cases.
+
+ * sem_warn.adb (Set_Warning_Flag): Clean up gnatwA list and ensure
+ completeness.
+ (Set_Dot_Warning_Flag): Ditto for -gnatw.e
+ (Set_Dot_Warning_Flag): Implement -gnbatw.v/w.V
+ * usage.adb: Add lines for -gnatw.v/w.V
+
+2009-11-30 Emmanuel Briot <briot@adacore.com>
+
+ * make.adb (Check_Standard_Library): use Full_Source_Name instead of
+ direct call to Find_File. The former provides caching of the results, so
+ might be more efficient
+ (Start_Compile_If_Necessary): Add comment on possible optimization,
+ not done for now.
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * g-sechas.adb: Minor reformatting
+
+2009-11-30 Matthew Heaney <heaney@adacore.com>
+
+ * a-crbtgo.adb (Delete_Fixup): Add comments explaining why predicates
+ were removed.
+ * a-cdlili.adb (Vet): Remove always-true predicates.
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * s-sechas.adb, s-sechas.ads, s-shshco.adb, s-shshco.ads, s-shsh64.adb,
+ s-shsh64.ads, s-sehamd.adb, s-sehamd.ads, s-shsh32.adb, s-shsh32.ads,
+ s-sehash.adb, s-sehash.ads, g-sechas.adb, g-sechas.ads, g-shshco.adb,
+ g-shshco.ads, g-md5.ads, g-sha256.ads, g-shsh64.adb, g-shsh64.ads,
+ g-sehamd.adb, g-sehamd.ads, g-sha512.ads, g-sha1.ads, Makefile.rtl,
+ g-sha224.ads, g-shsh32.adb, g-shsh32.ads, g-sha384.ads, g-sehash.adb,
+ g-sehash.ads: Rename System.Secure_Hashes to GNAT.Secure_Hashes.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * osint.ads: Minor comment update.
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * s-sechas.adb: Fix swapping error in previous checkin.
+ * g-md5.ads, g-sha256.ads, g-sha512.ads, g-sha1.ads, g-sha224.ads,
+ g-sha384.ads: Add missing documentation.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * g-sha256.ads, s-sehamd.ads, s-sehamd.adb, g-sha512.ads, g-sha224.ads,
+ g-sha384.ads: Minor reformatting
+
+2009-11-30 Emmanuel Briot <briot@adacore.com>
+
+ * adaint.h (file_attributes): Reduce size of the structure, so that it
+ is less costly to store in records.
+ * makeutl.adb:
+ (Check_Source_Info_In_ALI): use Full_Source_Name instead of a direct
+ call to Find_File, since the former provides caching when appropriate,
+ which limits the number of system calls in some cases.
+ * osint.ads, prj.ads (Source_Data): do not store directly the timestamp,
+ but the file attributes since we also need access to the size of the
+ ALI file to parse it. This gives an opportunity for saving system calls
+ on Unix systems.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * sem_prag.adb, s-sechas.ads, s-sechas.adb: Minor reformatting.
+
+2009-11-30 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_prag.adb (Process_Convention): Change formal E to Ent. In the
+ case where the pragma's entity argument is a renaming, return the
+ entity denoted by the renaming rather than the renamed entity. Loop
+ through the homonyms of the original argument entity, rather than the
+ homonyms of any renamed entity. Correct call to Generate_Entity to
+ pass the homonym.
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * impunit.adb: Add packages that were added to the GNAT library:
+ GNAT.SHA224, GNAT.SHA256, GNAT.SHA384 and GNAT.SHA512.
+ * s-sechas.adb (Fill_Buffer_Copy): Fixes incorrect slice index
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * exp_ch3.adb: Minor reformatting
+ * g-md5.ads, g-sha1.ads: Add comment.
+
+2009-11-30 Arnaud Charlet <charlet@adacore.com>
+
+ * gcc-interface/Makefile.in: Remove handling of libgccprefix, no longer
+ needed.
+
+2009-11-30 Pascal Obry <obry@adacore.com>
+
+ * expect.c: Fix cast to avoid warnings in x86-64 Windows.
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * gnat_rm.texi, s-sechas.adb, s-sechas.ads, s-shshco.adb,
+ s-shshco.ads, g-md5.adb, g-md5.ads, g-sha256.ads, s-shsh64.adb,
+ s-shsh64.ads, s-sehamd.adb, s-sehamd.ads, g-sha512.ads, g-sha1.adb,
+ g-sha1.ads, Makefile.rtl, g-sha224.ads, g-sha384.ads, s-shsh32.adb,
+ s-shsh32.ads, s-sehash.adb, s-sehash.ads: Reimplementation of GNAT.MD5
+ and GNAT.SHA1 to factor shared code and avoid unnecessary stack copies.
+ Also introduce new functions SHA-{224,256,384,512}
+
+2009-11-30 Jerome Lambourg <lambourg@adacore.com>
+
+ * exp_ch3.adb (Make_Predefined_Primitive_Specs): Improve comment for
+ the Value_Type case.
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * a-textio.adb: Minor reformatting
+
+2009-11-30 Pascal Obry <obry@adacore.com>
+
+ * adaint.c: Fix bug in passing parameter.
+ * expect.c: Include io.h to get definition of _open_osfhandle
+
+2009-11-30 Javier Miranda <miranda@adacore.com>
+
+ * exp_ch6.adb, sem_scil.adb (Adjust_SCIL_Node): Add missing management
+ of N_Unchecked_Type_Conversion nodes when searching for SCIL nodes.
+ (Expand_Call): Adjust decoration of SCIL node associated with relocated
+ function call.
+
+2009-11-30 Emmanuel Briot <briot@adacore.com>
+
+ * prj-env.adb (Add_To_Source_Path): Preserve casing of directories
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * opt.ads (No_Split_Units): New flag initialized to False
+
+2009-11-30 Jerome Lambourg <lambourg@adacore.com>
+
+ * exp_ch7.adb (Needs_Finalization): Add comments.
+ * exp_ch3.adb (Make_Predefined_Primitive_Specs): Improve handling of
+ CIL Value types.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * osint.adb, a-rttiev.adb: Minor reformatting.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * gnat_rm.texi: Remove list of warning letters, and refer instead to
+ using gnatmake to get a brief list.
+
+ * debug.adb: Document -gnatd.i to disable pragma Warnings
+ * par-prag.adb, sem_prag.adb: Recognize -gnatd.i to disable Warnings
+ pragma.
+ * vms_data.ads: Add /NOWARNINGS_PRAGMS for -gnatd.i
+
+2009-11-30 Geert Bosch <bosch@adacore.com>
+
+ * a-ngelfu.adb (Sin): Correct spelling of sine in comment.
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * gnatls.adb: Do not call Get_Target_Parameters in Verbose_Mode, as it
+ is not needed and gnatls fails when called with -v -nostdinc.
+
+2009-11-30 Emmanuel Briot <briot@adacore.com>
+
+ * osint.adb, osint.ads (File_Time_Stamp): new subprogram.
+
+2009-11-30 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat_rm.texi, gnat_ugn.texi: Document new syntax for pragma Annotate
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * scans.ads (Wide_Wide_Character_Found): New flag
+ * scn.adb (Post_Scan): Set new flag Has_Wide_Wide_Character
+ * scng.adb (Set_String): Set new flag Wide_Wide_Character_Found
+ (Set_String): Fix failure to reset Wide_Character_Found
+ * sinfo.adb (Has_Wide_Wide_Character): New flag in N_String_Literal
+ * sinfo.ads (Has_Wide_Wide_Character): New flag in N_String_Literal
+ * a-ngelfu.adb: Minor reformatting & code reorganization.
+ * usage.adb: Fix typo in -gnatw.W line
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * osint.adb, prj-nmsc.adb, sem_prag.adb, sem_util.adb: Minor
+ reformatting.
+ * csinfo.adb: Terminate run if improper use of reserved flag
+ * sinfo.ads, sinfo.adb (Is_Accessibility_Actual): Don't use reserved
+ Flag12, used Flag13 instead.
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * gnatcmd.adb (Check_Files): Recognize documented switches that have a
+ separate parameter.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * sem_util.ads: Minor reformatting
+ * errout.adb: Minor reformatting
+ Minor code reorganization (use N_Subprogram_Specification to simplify)
+ * exp_ch7.adb: Add comment.
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * put_scos.adb (Put_SCOs): Do not generate a SCO unit header for a unit
+ that has no SCOs.
+ * scos.ads: Minor reformatting
+
+2009-11-30 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_prag.adb: Second unanalyzed parameter of Annotate is optional.
+
+2009-11-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ * init.c (__gnat_adjust_context_for_raise, Linux version): Add guard
+ for null PC saved in the context.
+
+2009-11-30 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * a-calend.adb (Day_Of_Week): Rewritten. The routine determines the
+ number of days from the Ada Epoch to the input date while ensuring that
+ both dates are in the same time zone.
+
+2009-11-30 Emmanuel Briot <briot@adacore.com>
+
+ * clean.adb ("-eL"): Also set Follow_Links_For_Dirs, to match what is
+ done in other project-aware tools like gnatmake and gprbuild.
+
+2009-11-30 Jerome Lambourg <lambourg@adacore.com>
+
+ * exp_ch3.adb (Make_Predefined_Primitive_Specs): Take care of CIL
+ ValueTypes.
+ * exp_ch7.adb (Needs_Finalization): Do not finalize CIL valuetypes.
+ * sem_util.adb (Is_Value_Type): Protect against invalid calls to Chars
+ (Is_Delegate): New method used for CIL.
+ * sem_util.ads (Is_Delegate): New method for CIL handling.
+ (Is_Value_Type): Improve documentation.
+
+2009-11-30 Ed Schonberg <schonberg@adacore.com>
+
+ * errout.adb (Unwind_Internal_Type): Improve error reporting if the
+ type is an anonymous access to subprogram that is the type of a formal
+ in a subprogram spec.
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * prj-nmsc.adb (Check_Interfaces): In a Stand-Alone Library project, if
+ attribute Interfaces is not declared, then Library_Interface should
+ define the interfaces.
+
+2009-11-30 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_prag.adb: New semantics for Annotate.
+
+2009-11-30 Tristan Gingold <gingold@adacore.com>
+
+ * gcc-interface/Makefile.in: Do not link with -static-libgcc on Darwin.
+
+2009-11-30 Emmanuel Briot <briot@adacore.com>
+
+ * gnat_ugn.texi: Extend doc for -eL
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * osint.adb (Executable_Name (File_Name_Type)): Put the Name in the
+ Name_Buffer before testing for a dot in the Name.
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * prj-part.adb (Project_Path_Name_Of): Resolve links for final result
+ if -eL has been specified.
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * osint.adb (Executable_Name): Test the name instead of the name buffer
+ to check if there is a dot in the given name.
+
+2009-11-30 Sergey Rybin <rybin@adacore.com>
+
+ * gnat_ugn.texi: Update gnatcheck doc.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * sem_ch3.adb, sem_disp.adb, usage.adb: Minor reformatting
+
+2009-11-30 Vasiliy Fofanov <fofanov@adacore.com>
+
+ * gnat_ugn.texi: Minor editing.
+
+2009-11-30 Emmanuel Briot <briot@adacore.com>
+
+ * prj-nmsc.adb (Search_Directories): when -eL was not specified, assume
+ that no directory matches the naming scheme for sources.
+
+2009-11-30 Emmanuel Briot <briot@adacore.com>
+
+ * prj.adb, prj.ads, prj-nmsc.adb (Has_Multi_Unit_Sources): New field in
+ project_data.
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * osint.adb (Executable_Name): Correctly decide if the executable
+ suffix should be added when Only_If_No_Suffix is True.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * frontend.adb, gnatlink.adb, prj-conf.adb, prj-tree.adb,
+ prj-tree.ads: Minor reformatting
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * gnatlink.adb (Process_Args): Call Executable_Name on argument of -o
+ with Only_If_No_Suffix set to True.
+ * osint.adb (Executable_Name): Do not add executable suffix if there is
+ already a suffix and Only_If_No_Suffix is True.
+ * osint.ads (Executable_Name): New Boolean parameter Only_If_No_Suffix,
+ defaulted to False.
+
+2009-11-30 Javier Miranda <miranda@adacore.com>
+
+ * exp_atag.adb (Build_TSD): Change argument name because the actual is
+ now the address of a tag (instead of the tag). Update implementation
+ accordingly.
+ (Build_CW_Membership): New implementation. Converted into a procedure
+ because it has an additional out mode parameter. Its implementation has
+ been rewritten to improve the generated code but also to facilitate
+ referencing the relocated object node in the caller.
+ * exp_atag.ads (Build_CW_Membership): Update profile and documentation.
+ * sinfo.ads (N_SCIL_Membership_Test) New_Node.
+ (SCIL_Tag_Value): New field of N_SCIL_Membership_Test nodes.
+ (Is_Syntactic_Field): Add entry of new node.
+ (SCIL_Tag_Value/Set_SCIL_Tag_Value): New subprograms.
+ * sinfo.adb (SCIL_Related_Node, SCIL_Entity): Update assertions to
+ handle N_SCIL_Membership_Test nodes.
+ (SCIL_Tag_Value/Set_SCIL_Tag_Value): New subprograms.
+ * sem.adb (Analyze): Add null management for new node.
+ * sem_scil.adb (Find_SCIL_Node): Add null management for new node.
+ (Check_SCIL_Node): Add checks of N_SCIL_Membership_Test nodes.
+ * exp_ch4.adb (Tagged_Membership): Change profile from function to
+ procedure. Add generation of SCIL node associated with class-wide
+ membership test.
+ (Expand_N_In): Complete decoration of SCIL nodes.
+ * exp_intr.adb (Expand_Dispatching_Constructor_Call): Tune call to
+ Build_CW_Membership because its profile has been changed.
+ * exp_util.adb (Insert_Actions): Add null management for new node.
+ * sprint.adb (Sprint_Node_Actual): Handle new node.
+ * gcc-interface/trans.c Add no processing for N_SCIL_Membership_Test
+ nodes.
+ * gcc-interface/Make-lang.in: Update dependencies.
+
+2009-11-30 Ed Schonberg <schonberg@adacore.com>
+
+ * opt.ads: New flags Init_Or_Norm_Scalars_Config,
+ Initialize_Scalars_Config, to capture the presence of the corresponding
+ pragmas in a configuration file.
+ * opt.adb (Register_, Save_, Set_, Restore_Opt_Configuration_Switches):
+ handle new flags so that they are restored for each compilation unit.
+ * frontend.adb: At the end of compilation, scan the context of the main
+ unit to recover occurrences of pragma Initialize_Scalars, to annotate
+ the ALI file accordingly.
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * prj-tree.ads: Minor comment updates
+ * prj-tree.adb: Minor reformatting
+
+2009-11-30 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch3.adb (Derive_Subprogram): Indicate that an inherited
+ predefined control operation is hidden if the parent type is not
+ visibly controlled.
+ * sem_ch6.adb (Check_Overriding_Indicator): Do not report error if
+ overridden operation is not visible, as may be the case with predefined
+ control operations.
+ * sem_disp.adb (Check_Dispatching_Operation): Do not emit warning on
+ non-overriding control operation when type is not visibly controlled,
+ if the subprogram has an explicit overriding indicator.
+ * sem_util.ads, sem_util.adb (Is_Visibly_Controlled): Moved here from
+ sem_disp.adb.
+
+2009-11-30 Emmanuel Briot <briot@adacore.com>
+
+ * prj-tree.adb (Create_Attribute): Fix handling of VMS and Windows
+ * prj-attr.ads: Minor comment updates
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * gnat_rm.texi: Document pragma Short_Circuit
+
+2009-11-30 Emmanuel Briot <briot@adacore.com>
+
+ * prj-conf.adb, prj-tree.adb, prj-tree.ads (Create_Attribute): Now set
+ the index either on the attribute or on its value, depending on the
+ kind of the attribute. Done to match recent changes in Prj.PP that were
+ not synchronized with this function.
+
+2009-11-30 Arnaud Charlet <charlet@adacore.com>
+
+ * gcc-interface/Make-lang.in: Fix typo.
+ Update dependencies.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * gnat_rm.texi: Add documentation for attribute Result.
+
+2009-11-30 Arnaud Charlet <charlet@adacore.com>
+
+ * s-osinte-hpux.ads, s-osinte-aix.ads, s-osinte-solaris-posix.ads,
+ s-osinte-tru64.ads, s-osinte-darwin.ads, s-osinte-freebsd.ads
+ (Get_Page_Size): Update comment since Get_Page_Size is now required.
+
+2009-11-30 Jerome Lambourg <lambourg@adacore.com>
+
+ * freeze.adb: Disable Warning on VM targets concerning C Imports, not
+ relevant.
+
+2009-11-30 Bob Duff <duff@adacore.com>
+
+ * sprint.adb (Source_Dump): Minor comment fix.
+ (Write_Itype): When writing a string literal subtype, use Expr_Value
+ instead of Intval to get the low bound.
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * gnatlink.adb (Process_Args): Do not call Executable_Name on arguments
+ of switch -o.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Op_And): Implement pragma Short_Circuit_And_Or
+ (Expand_N_Op_Or): Implement pragma Short_Circuit_And_Or
+ * opt.ads (Short_Circuit_And_Or): New flag
+ * par-prag.adb: Add dummy entry for pragma Short_Circuit_And_Or
+ * sem_prag.adb: Implement pragma Short_Circuit_And_Or
+ * snames.ads-tmpl: Add entries for pragma Short_Circuit_And_Or
+
+2009-11-30 Arnaud Charlet <charlet@adacore.com>
+
+ * s-taprop-posix.adb: Fix casing.
+ * s-osinte-tru64.adb: Complete previous check-in.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * gnat_rm.texi: Document pragma Compiler_Unit
+ * s-bitops.adb, s-restri.adb, g-htable.adb, s-restri.ads,
+ a-comlin.ads, a-strhas.ads, s-strhas.adb, s-parame.adb,
+ s-parame.ads, a-clrefi.adb, a-clrefi.ads, a-ioexce.ads: Supply missing
+ Compiler_Unit pragmas.
+ * freeze.adb (Freeze_Entity): Improve message for 8-bit boolean passed
+ to C.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * makeutl.adb, makeutl.ads, prj-proc.adb, prj.adb, prj.ads: Minor
+ reformatting.
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * osint.adb: Minor reformatting
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * makeutl.ads, makeutl.adb (Base_Name_Index_For): New function to get
+ the base name of a main without the extension, with an eventual source
+ index.
+ (Mains.Get_Index): New procedure to set the source index of a main
+ (Mains.Get_Index): New function to get the source index of a main
+ * prj-attr.adb: New attributes Config_Body_File_Name_Index,
+ Config_Spec_File_Name_Index, Multi_Unit_Object_Separator and
+ Multi_Unit_Switches.
+ * prj-nmsc.adb (Process_Compiler): Takle into account new attributes
+ Config_Body_File_Name_Index, Config_Spec_File_Name_Index,
+ Multi_Unit_Object_Separator and Multi_Unit_Switches.
+ Allow only one character for Multi_Unit_Object_Separator.
+ * prj-proc.adb (Process_Declarative_Items): Take into account the
+ source indexes in indexes of associative array attribute declarations.
+ * prj.adb (Object_Name): New function to get the object file name for
+ units in multi-unit sources.
+ * prj.ads (Language_Config): New components Multi_Unit_Switches,
+ Multi_Unit_Object_Separator Config_Body_Index and Config_Spec_Index.
+ (Object_Name): New function to get the object file name for units in
+ multi-unit sources.
+ * snames.ads-tmpl: New standard names Config_Body_File_Name_Index,
+ Config_Spec_File_Name_Index, Multi_Unit_Object_Separator and
+ Multi_Unit_Switches.
+
+2009-11-30 Arnaud Charlet <charlet@adacore.com>
+
+ * s-tassta.adb: Update comment.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * a-ngelfu.adb: Minor code reorganization.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * osint.ads, prj.adb, prj.ads: Minor reformatting
+ * s-stchop.adb, s-taprop-vxworks.adb, s-taprop-tru64.adb,
+ s-taprop-vms.adb, s-taprop-linux.adb, s-taprop-solaris.adb,
+ s-strxdr.adb, s-taprop-irix.adb, s-osinte-hpux-dce.adb,
+ s-osinte-tru64.adb, s-taenca.adb, s-taprop-hpux-dce.adb, s-stausa.adb,
+ s-taprop-posix.adb: Minor code reorganization (use conditional
+ expressions).
+
+2009-11-30 Bob Duff <duff@adacore.com>
+
+ * g-sttsne-locking.adb (Copy_Service_Entry): Complete previous change.
+
+2009-11-30 Bob Duff <duff@adacore.com>
+
+ * socket.c: Add more accessor functions for struct servent (need
+ setters as well as getters).
+ * g-sothco.ads (Servent): Declare interfaces to C setter functions for
+ struct servent.
+ * g-sttsne-locking.adb (Copy_Service_Entry): Use setter functions for
+ struct servent.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * s-stchop-vxworks.adb: Add comment.
+
+2009-11-30 Emmanuel Briot <briot@adacore.com>
+
+ * make.adb, prj.adb, prj.ads (Compute_All_Imported_Projects): Now acts
+ on the whole tree, to better share code with gprbuild.
+ (Length): New subprogram, to share code in gprbuild.
+ (Project_Data): Remove fields that are only needed when compiling a
+ project in gprbuild (where we use local variables instead)
+ * osint.adb, osint.ads: Added minor comment on memory management
+
+2009-11-30 Sergey Rybin <rybin@adacore.com>
+
+ * gnat_ugn.texi: Update gnatcheck doc.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ make.adb, prj-makr.adb, g-sothco.ads: Minor reformattting
+ * s-taprop-dummy.adb: Minor code reorganization (raise with msgs start
+ with lower case).
+ * i-vxwoio.adb, g-dirope.adb, g-sercom-linux.adb,
+ g-enblsp-vms-alpha.adb, g-regist.adb, s-imgcha.adb, s-tarest.adb,
+ s-taprop-mingw.adb, g-exctra.adb, g-expect.adb, g-comlin.adb,
+ g-debpoo.adb, g-expect-vms.adb, g-pehage.adb, g-trasym-vms-alpha.adb,
+ g-enblsp-vms-ia64.adb, s-fatgen.adb, s-fileio.adb: Minor code
+ reorganization (use conditional expressions).
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * prj-makr.adb (Source_Files): New hash table to keep track of source
+ file names.
+ (Finalize): Avoid putting several times the same source file name
+ in the source list file.
+ * prj-pp.adb (Print): Fix a bug in the placement of "at nn" for
+ associative array indexes.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * g-dyntab.ads: Add missing pragma Compiler_Unit
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * s-crtrun.ads, s-crtl.ads, g-stseme.adb, Makefile.rtl, s-fileio.adb
+ (System.CRTL.Runtime): New unit, to contain parts of s-crtl that are
+ used in the Ada runtime but can't be used in the compiler because of
+ bootstrap issues.
+ * socket.c, s-oscons-tmplt.c, g-sothco.ads
+ (System.OS_Constants.SIZEOF_struct_servent): New constant.
+ Use s-oscons constant instead of external variable to get size of
+ struct hostent.
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * s-crtl.ads, g-stseme.adb, s-fileio.adb (System.CRTL.strerror): Change
+ return type to Interfaces.C.Strings.chars_ptr to eliminate need for
+ dubious unchecked conversion at call sites.
+ * s-errrep.adb, s-errrep.ads, Makefile.rtl (System.Error_Reporting):
+ Remove obsolete, unused runtime unit.
+ * gcc-interface/Make-lang.in: Update dependencies.
+ * gcc-interface/Makefile.in: Remove VMS specialization of s-crtl, not
+ required anymore.
+
+2009-11-30 Vincent Celier <celier@adacore.com>
+
+ * gnatlink.adb: Delete an eventual existing executable file, in case it
+ is a symbolic link, to avoid modifying the target of the symbolic link.
+
+2009-11-30 Bob Duff <duff@adacore.com>
+
+ * socket.c: Add accessor functions for struct servent.
+ * g-sothco.ads (Servent): Declare interfaces to C accessor functions
+ for struct servent.
+ * g-socket.adb (To_Service_Entry): Use accessor functions for struct
+ servent.
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * g-arrspl.adb: Minor reformatting
+ * g-dyntab.adb: Add missing pragma Compiler_Unit
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * s-crtl.ads, s-oscons-tmplt.c: Fix support for VMS
+ * make.adb, g-comlin.ads, exp_ch6.adb: Minor reformatting
+
+2009-11-30 Robert Dewar <dewar@adacore.com>
+
+ * bcheck.adb, gnatlink.adb, make.adb, makeutl.adb, osint.adb,
+ osint.ads, prj-ext.adb, sem_case.adb: Minor reformatting
+ * g-alleve.adb: Minor code reorganization (use conditional expressions)
+
+2009-11-30 Matthew Heaney <heaney@adacore.com>
+
+ * a-crbtgo.adb (Delete_Fixup): Changed always-true predicates to
+ assertions.
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * a-tasatt.adb, s-crtl.ads, s-taprop-dummy.adb (System.CRTL.malloc32,
+ System.CRTL.realloc32): Remove VMS-specific routines.
+ (Ada.Task_Attributes.Reference): Remove unreachable code.
+ (System.Task_Primitives.Operations.Initialize, dummy version):
+ Use plain Program_Error rather than call to
+ System.Error_Reporting.Shutdown.
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * s-oscons-tmplt.c, xoscons.adb: Add new constants in preparation for
+ sharing s-crtl across all platforms.
+
+2009-11-30 Thomas Quinot <quinot@adacore.com>
+
+ * s-commun.adb, s-commun.ads: New internal support unit,
+ allowing code sharing between GNAT.Sockets and
+ GNAT.Serial_Communication.
+ * g-sercom.ads, g-sercom-mingw.adb, g-sercom-linux.adb,
+ g-socket.adb (GNAT.Sockets.Last_Index): Move to System.Communication.
+ (GNAT.Serial_Communication.Read): Handle correctly the case where no
+ data was read, and Buffer'First = Stream_Element_Offset'First.
+ * Makefile.rtl: Add entry for s-commun
+ * g-socthi-vms.adb, g-socthi-vms.ads, g-socthi-vxworks.adb,
+ g-socthi-vxworks.ads, g-stseme.adb, g-socthi-mingw.ads,
+ g-socthi.adb, g-socthi.ads (GNAT.Sockets.Thin.Socket_Error_Message):
+ Reimplement in terms of System.CRTL.strerror.
+
2009-11-26 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/utils.c (copy_type): Unshare the language-specific data
diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 4f26f1569b5..f101a52e025 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -80,9 +80,9 @@ GNATRTL_TASKING_OBJS= \
GNATRTL_NONTASKING_OBJS= \
a-assert$(objext) \
a-calari$(objext) \
+ a-calcon$(objext) \
a-caldel$(objext) \
a-calend$(objext) \
- a-calcon$(objext) \
a-calfor$(objext) \
a-catizo$(objext) \
a-cdlili$(objext) \
@@ -146,12 +146,12 @@ GNATRTL_NONTASKING_OBJS= \
a-izteio$(objext) \
a-lcteio$(objext) \
a-lfteio$(objext) \
- a-llctio$(objext) \
a-lfwtio$(objext) \
a-lfztio$(objext) \
a-liteio$(objext) \
a-liwtio$(objext) \
a-liztio$(objext) \
+ a-llctio$(objext) \
a-llftio$(objext) \
a-llfwti$(objext) \
a-llfzti$(objext) \
@@ -239,9 +239,9 @@ GNATRTL_NONTASKING_OBJS= \
a-szuzha$(objext) \
a-szuzti$(objext) \
a-tags$(objext) \
- a-tgdico$(objext) \
a-teioed$(objext) \
a-textio$(objext) \
+ a-tgdico$(objext) \
a-tiboio$(objext) \
a-ticoau$(objext) \
a-ticoio$(objext) \
@@ -337,18 +337,18 @@ GNATRTL_NONTASKING_OBJS= \
g-crc32$(objext) \
g-ctrl_c$(objext) \
g-curexc$(objext) \
- g-debuti$(objext) \
g-debpoo$(objext) \
+ g-debuti$(objext) \
g-decstr$(objext) \
g-deutst$(objext) \
g-diopit$(objext) \
g-dirope$(objext) \
- g-dyntab$(objext) \
g-dynhta$(objext) \
+ g-dyntab$(objext) \
g-encstr$(objext) \
g-enutst$(objext) \
- g-except$(objext) \
g-excact$(objext) \
+ g-except$(objext) \
g-exctra$(objext) \
g-expect$(objext) \
g-flocon$(objext) \
@@ -367,12 +367,22 @@ GNATRTL_NONTASKING_OBJS= \
g-rannum$(objext) \
g-regexp$(objext) \
g-regpat$(objext) \
+ g-sechas$(objext) \
+ g-sehamd$(objext) \
+ g-sehash$(objext) \
g-sercom$(objext) \
g-sestin$(objext) \
g-sha1$(objext) \
+ g-sha224$(objext) \
+ g-sha256$(objext) \
+ g-sha384$(objext) \
+ g-sha512$(objext) \
+ g-shsh32$(objext) \
+ g-shsh64$(objext) \
+ g-shshco$(objext) \
g-souinf$(objext) \
- g-speche$(objext) \
g-spchge$(objext) \
+ g-speche$(objext) \
g-spipat$(objext) \
g-spitbo$(objext) \
g-sptabo$(objext) \
@@ -384,8 +394,8 @@ GNATRTL_NONTASKING_OBJS= \
g-tasloc$(objext) \
g-timsta$(objext) \
g-traceb$(objext) \
- g-utf_32$(objext) \
g-u3spch$(objext) \
+ g-utf_32$(objext) \
g-wispch$(objext) \
g-wistsp$(objext) \
g-zspche$(objext) \
@@ -421,6 +431,7 @@ GNATRTL_NONTASKING_OBJS= \
s-caun32$(objext) \
s-caun64$(objext) \
s-chepoo$(objext) \
+ s-commun$(objext) \
s-conca2$(objext) \
s-conca3$(objext) \
s-conca4$(objext) \
@@ -429,13 +440,13 @@ GNATRTL_NONTASKING_OBJS= \
s-conca7$(objext) \
s-conca8$(objext) \
s-conca9$(objext) \
- s-crtl$(objext) \
s-crc32$(objext) \
+ s-crtl$(objext) \
+ s-crtrun$(objext) \
s-direio$(objext) \
s-dsaser$(objext) \
- s-errrep$(objext) \
- s-exctab$(objext) \
s-except$(objext) \
+ s-exctab$(objext) \
s-exnint$(objext) \
s-exnllf$(objext) \
s-exnlli$(objext) \
@@ -452,14 +463,15 @@ GNATRTL_NONTASKING_OBJS= \
s-ficobl$(objext) \
s-fileio$(objext) \
s-filofl$(objext) \
- s-fishfl$(objext) \
s-finimp$(objext) \
s-finroo$(objext) \
+ s-fishfl$(objext) \
s-fore$(objext) \
s-fvadfl$(objext) \
s-fvaffl$(objext) \
s-fvagfl$(objext) \
s-geveop$(objext) \
+ s-gloloc$(objext) \
s-htable$(objext) \
s-imenne$(objext) \
s-imgbiu$(objext) \
@@ -478,10 +490,11 @@ GNATRTL_NONTASKING_OBJS= \
s-imgwch$(objext) \
s-imgwiu$(objext) \
s-io$(objext) \
- s-gloloc$(objext) \
s-maccod$(objext) \
s-mantis$(objext) \
s-mastop$(objext) \
+ s-memcop$(objext) \
+ s-memory$(objext) \
s-os_lib$(objext) \
s-osprim$(objext) \
s-pack03$(objext) \
@@ -558,19 +571,17 @@ GNATRTL_NONTASKING_OBJS= \
s-secsta$(objext) \
s-sequio$(objext) \
s-shasto$(objext) \
+ s-soflin$(objext) \
s-stache$(objext) \
+ s-stalib$(objext) \
s-stausa$(objext) \
s-stchop$(objext) \
- s-stalib$(objext) \
s-stoele$(objext) \
s-stopoo$(objext) \
s-stratt$(objext) \
s-strhas$(objext) \
- s-ststop$(objext) \
- s-soflin$(objext) \
- s-memory$(objext) \
- s-memcop$(objext) \
s-string$(objext) \
+ s-ststop$(objext) \
s-tasloc$(objext) \
s-traceb$(objext) \
s-traces$(objext) \
diff --git a/gcc/ada/a-calend.adb b/gcc/ada/a-calend.adb
index 1a49c58888a..dd500f43691 100644
--- a/gcc/ada/a-calend.adb
+++ b/gcc/ada/a-calend.adb
@@ -1029,63 +1029,40 @@ package body Ada.Calendar is
-----------------
function Day_Of_Week (Date : Time) return Integer is
- Y : Year_Number;
- Mo : Month_Number;
- D : Day_Number;
- Ds : Day_Duration;
- H : Integer;
- Mi : Integer;
- Se : Integer;
- Su : Duration;
- Le : Boolean;
-
- pragma Unreferenced (Ds, H, Mi, Se, Su, Le);
+ Date_N : constant Time_Rep := Time_Rep (Date);
+ Time_Zone : constant Long_Integer :=
+ Time_Zones_Operations.UTC_Time_Offset (Date);
+ Ada_Low_N : Time_Rep;
Day_Count : Long_Integer;
- Res_Dur : Time_Dur;
- Res_N : Time_Rep;
+ Day_Dur : Time_Dur;
+ High_N : Time_Rep;
+ Low_N : Time_Rep;
begin
- Formatting_Operations.Split
- (Date => Date,
- Year => Y,
- Month => Mo,
- Day => D,
- Day_Secs => Ds,
- Hour => H,
- Minute => Mi,
- Second => Se,
- Sub_Sec => Su,
- Leap_Sec => Le,
- Is_Ada_05 => True,
- Time_Zone => 0);
-
- -- Build a time value in the middle of the same day
-
- Res_N :=
- Time_Rep
- (Formatting_Operations.Time_Of
- (Year => Y,
- Month => Mo,
- Day => D,
- Day_Secs => 0.0,
- Hour => 12,
- Minute => 0,
- Second => 0,
- Sub_Sec => 0.0,
- Leap_Sec => False,
- Use_Day_Secs => False,
- Is_Ada_05 => True,
- Time_Zone => 0));
+ -- As declared, the Ada Epoch is set in UTC. For this calculation to
+ -- work properly, both the Epoch and the input date must be in the
+ -- same time zone. The following places the Epoch in the input date's
+ -- time zone.
+
+ Ada_Low_N := Ada_Low - Time_Rep (Time_Zone) * Nano;
+
+ if Date_N > Ada_Low_N then
+ High_N := Date_N;
+ Low_N := Ada_Low_N;
+ else
+ High_N := Ada_Low_N;
+ Low_N := Date_N;
+ end if;
-- Determine the elapsed seconds since the start of Ada time
- Res_Dur := Time_Dur (Res_N / Nano - Ada_Low / Nano);
+ Day_Dur := Time_Dur (High_N / Nano - Low_N / Nano);
- -- Count the number of days since the start of Ada time. 1901-1-1
+ -- Count the number of days since the start of Ada time. 1901-01-01
-- GMT was a Tuesday.
- Day_Count := Long_Integer (Res_Dur / Secs_In_Day) + 1;
+ Day_Count := Long_Integer (Day_Dur / Secs_In_Day) + 1;
return Integer (Day_Count mod 7);
end Day_Of_Week;
diff --git a/gcc/ada/a-cdlili.adb b/gcc/ada/a-cdlili.adb
index f9d7db832da..c2e0d9d0a0a 100644
--- a/gcc/ada/a-cdlili.adb
+++ b/gcc/ada/a-cdlili.adb
@@ -1711,12 +1711,18 @@ package body Ada.Containers.Doubly_Linked_Lists is
return False;
end if;
+ -- If we get here, we know that this disjunction is true:
+ -- Position.Node.Prev /= null or else Position.Node = L.First
+
if Position.Node.Next = null
and then Position.Node /= L.Last
then
return False;
end if;
+ -- If we get here, we know that this disjunction is true:
+ -- Position.Node.Next /= null or else Position.Node = L.Last
+
if L.Length = 1 then
return L.First = L.Last;
end if;
@@ -1761,21 +1767,21 @@ package body Ada.Containers.Doubly_Linked_Lists is
return False;
end if;
- if Position.Node = L.First then
+ if Position.Node = L.First then -- eliminates ealier disjunct
return True;
end if;
- if Position.Node = L.Last then
- return True;
- end if;
+ -- If we get here, we know, per disjunctive syllogism (modus
+ -- tollendo ponens), that this predicate is true:
+ -- Position.Node.Prev /= null
- if Position.Node.Next = null then
- return False;
+ if Position.Node = L.Last then -- eliminates earlier disjunct
+ return True;
end if;
- if Position.Node.Prev = null then
- return False;
- end if;
+ -- If we get here, we know, per disjunctive syllogism (modus
+ -- tollendo ponens), that this predicate is true:
+ -- Position.Node.Next /= null
if Position.Node.Next.Prev /= Position.Node then
return False;
diff --git a/gcc/ada/a-clrefi.adb b/gcc/ada/a-clrefi.adb
index 210e8615aa6..938ea18fb5e 100644
--- a/gcc/ada/a-clrefi.adb
+++ b/gcc/ada/a-clrefi.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2009, Free Software Foundation, Inc. --
+-- Copyright (C) 2007-2009, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -29,6 +29,8 @@
-- --
------------------------------------------------------------------------------
+pragma Compiler_Unit;
+
with Ada.Unchecked_Deallocation;
with System.OS_Lib; use System.OS_Lib;
diff --git a/gcc/ada/a-clrefi.ads b/gcc/ada/a-clrefi.ads
index 63b45881499..fdefafcccc9 100644
--- a/gcc/ada/a-clrefi.ads
+++ b/gcc/ada/a-clrefi.ads
@@ -36,6 +36,8 @@
-- Using a response file allow passing a set of arguments to an executable
-- longer than the maximum allowed by the system on the command line.
+pragma Compiler_Unit;
+
with System.Strings;
package Ada.Command_Line.Response_File is
diff --git a/gcc/ada/a-coinve.adb b/gcc/ada/a-coinve.adb
index 9169e086ebd..84ad22ec1f9 100644
--- a/gcc/ada/a-coinve.adb
+++ b/gcc/ada/a-coinve.adb
@@ -1121,21 +1121,45 @@ package body Ada.Containers.Indefinite_Vectors is
Index : constant Index_Type := Index_Type (Index_As_Int);
- J : Index_Type'Base := Before;
+ J : Index_Type'Base;
begin
+ -- The new items are being inserted in the middle of the
+ -- array, in the range [Before, Index). Copy the existing
+ -- elements to the end of the array, to make room for the
+ -- new items.
+
E (Index .. New_Last) := E (Before .. Container.Last);
Container.Last := New_Last;
- while J < Index loop
- E (J) := new Element_Type'(New_Item);
- J := J + 1;
- end loop;
+ -- We have copied the existing items up to the end of the
+ -- array, to make room for the new items in the middle of
+ -- the array. Now we actually allocate the new items.
- exception
- when others =>
- E (J .. Index - 1) := (others => null);
- raise;
+ -- Note: initialize J outside loop to make it clear that
+ -- J always has a value if the exception handler triggers.
+
+ J := Before;
+ begin
+ while J < Index loop
+ E (J) := new Element_Type'(New_Item);
+ J := J + 1;
+ end loop;
+
+ exception
+ when others =>
+
+ -- Values in the range [Before, J) were successfully
+ -- allocated, but values in the range [J, Index) are
+ -- stale (these array positions contain copies of the
+ -- old items, that did not get assigned a new item,
+ -- because the allocation failed). We must finish what
+ -- we started by clearing out all of the stale values,
+ -- leaving a "hole" in the middle of the array.
+
+ E (J .. Index - 1) := (others => null);
+ raise;
+ end;
end;
else
@@ -1149,6 +1173,9 @@ package body Ada.Containers.Indefinite_Vectors is
return;
end if;
+ -- There follows LOTS of code completely devoid of comments ???
+ -- This is not our general style ???
+
declare
C, CC : UInt;
diff --git a/gcc/ada/a-comlin.ads b/gcc/ada/a-comlin.ads
index a0335a49d72..8d66e1542b9 100644
--- a/gcc/ada/a-comlin.ads
+++ b/gcc/ada/a-comlin.ads
@@ -33,6 +33,8 @@
-- --
------------------------------------------------------------------------------
+pragma Compiler_Unit;
+
package Ada.Command_Line is
pragma Preelaborate;
diff --git a/gcc/ada/a-crbtgo.adb b/gcc/ada/a-crbtgo.adb
index 9b30226b066..c8ddcff02a5 100644
--- a/gcc/ada/a-crbtgo.adb
+++ b/gcc/ada/a-crbtgo.adb
@@ -49,6 +49,8 @@ package body Ada.Containers.Red_Black_Trees.Generic_Operations is
procedure Left_Rotate (Tree : in out Tree_Type; X : Node_Access);
procedure Right_Rotate (Tree : in out Tree_Type; Y : Node_Access);
+-- Why is all the following code commented out ???
+
-- ---------------------
-- -- Check_Invariant --
-- ---------------------
@@ -171,9 +173,14 @@ package body Ada.Containers.Red_Black_Trees.Generic_Operations is
if Right (W) = null
or else Color (Right (W)) = Black
then
- if Left (W) /= null then
- Set_Color (Left (W), Black);
- end if;
+ -- As a condition for setting the color of the left child to
+ -- black, the left child access value must be non-null. A
+ -- truth table analysis shows that if we arrive here, that
+ -- condition holds, so there's no need for an explicit test.
+ -- The assertion is here to document what we know is true.
+
+ pragma Assert (Left (W) /= null);
+ Set_Color (Left (W), Black);
Set_Color (W, Red);
Right_Rotate (Tree, W);
@@ -208,9 +215,15 @@ package body Ada.Containers.Red_Black_Trees.Generic_Operations is
else
if Left (W) = null or else Color (Left (W)) = Black then
- if Right (W) /= null then
- Set_Color (Right (W), Black);
- end if;
+
+ -- As a condition for setting the color of the right child
+ -- to black, the right child access value must be non-null.
+ -- A truth table analysis shows that if we arrive here, that
+ -- condition holds, so there's no need for an explicit test.
+ -- The assertion is here to document what we know is true.
+
+ pragma Assert (Right (W) /= null);
+ Set_Color (Right (W), Black);
Set_Color (W, Red);
Left_Rotate (Tree, W);
@@ -250,6 +263,8 @@ package body Ada.Containers.Red_Black_Trees.Generic_Operations is
"attempt to tamper with cursors (container is busy)";
end if;
+ -- Why are these all commented out ???
+
-- pragma Assert (Tree.Length > 0);
-- pragma Assert (Tree.Root /= null);
-- pragma Assert (Tree.First /= null);
diff --git a/gcc/ada/a-ioexce.ads b/gcc/ada/a-ioexce.ads
index 43239ddb066..44865ab6649 100644
--- a/gcc/ada/a-ioexce.ads
+++ b/gcc/ada/a-ioexce.ads
@@ -13,6 +13,8 @@
-- --
------------------------------------------------------------------------------
+pragma Compiler_Unit;
+
package Ada.IO_Exceptions is
pragma Pure;
diff --git a/gcc/ada/a-ngelfu.adb b/gcc/ada/a-ngelfu.adb
index 55d14e7db53..b615f9da957 100644
--- a/gcc/ada/a-ngelfu.adb
+++ b/gcc/ada/a-ngelfu.adb
@@ -35,8 +35,8 @@
-- advantage of the C functions, e.g. in providing interface to hardware
-- provided versions of the elementary functions.
--- Uses functions sqrt, exp, log, pow, sin, asin, cos, acos, tan, atan,
--- sinh, cosh, tanh from C library via math.h
+-- Uses functions sqrt, exp, log, pow, sin, asin, cos, acos, tan, atan, sinh,
+-- cosh, tanh from C library via math.h
with Ada.Numerics.Aux;
@@ -46,6 +46,7 @@ package body Ada.Numerics.Generic_Elementary_Functions is
Sqrt_Two : constant := 1.41421_35623_73095_04880_16887_24209_69807_85696;
Log_Two : constant := 0.69314_71805_59945_30941_72321_21458_17656_80755;
+
Half_Log_Two : constant := Log_Two / 2;
subtype T is Float_Type'Base;
@@ -63,14 +64,12 @@ package body Ada.Numerics.Generic_Elementary_Functions is
-----------------------
function Exp_Strict (X : Float_Type'Base) return Float_Type'Base;
- -- Cody/Waite routine, supposedly more precise than the library
- -- version. Currently only needed for Sinh/Cosh on X86 with the largest
- -- FP type.
+ -- Cody/Waite routine, supposedly more precise than the library version.
+ -- Currently only needed for Sinh/Cosh on X86 with the largest FP type.
function Local_Atan
- (Y : Float_Type'Base;
- X : Float_Type'Base := 1.0)
- return Float_Type'Base;
+ (Y : Float_Type'Base;
+ X : Float_Type'Base := 1.0) return Float_Type'Base;
-- Common code for arc tangent after cycle reduction
----------
@@ -121,9 +120,9 @@ package body Ada.Numerics.Generic_Elementary_Functions is
A_Right := abs (Right);
-- If exponent is larger than one, compute integer exponen-
- -- tiation if possible, and evaluate fractional part with
- -- more precision. The relative error is now proportional
- -- to the fractional part of the exponent only.
+ -- tiation if possible, and evaluate fractional part with more
+ -- precision. The relative error is now proportional to the
+ -- fractional part of the exponent only.
if A_Right > 1.0
and then A_Right < Float_Type'Base (Integer'Last)
@@ -241,8 +240,8 @@ package body Ada.Numerics.Generic_Elementary_Functions is
function Arccosh (X : Float_Type'Base) return Float_Type'Base is
begin
- -- Return positive branch of Log (X - Sqrt (X * X - 1.0)), or
- -- the proper approximation for X close to 1 or >> 1.
+ -- Return positive branch of Log (X - Sqrt (X * X - 1.0)), or the proper
+ -- approximation for X close to 1 or >> 1.
if X < 1.0 then
raise Argument_Error;
@@ -305,8 +304,8 @@ package body Ada.Numerics.Generic_Elementary_Functions is
raise Argument_Error;
else
- -- 1.0 < abs X <= 2.0. One of X + 1.0 and X - 1.0 is exact, the
- -- other has error 0 or Epsilon.
+ -- 1.0 < abs X <= 2.0. One of X + 1.0 and X - 1.0 is exact, the other
+ -- has error 0 or Epsilon.
return 0.5 * (Log (abs (X + 1.0)) - Log (abs (X - 1.0)));
end if;
@@ -394,9 +393,7 @@ package body Ada.Numerics.Generic_Elementary_Functions is
return Float_Type'Base
is
begin
- if X = 0.0
- and then Y = 0.0
- then
+ if X = 0.0 and then Y = 0.0 then
raise Argument_Error;
elsif Y = 0.0 then
@@ -407,11 +404,7 @@ package body Ada.Numerics.Generic_Elementary_Functions is
end if;
elsif X = 0.0 then
- if Y > 0.0 then
- return Half_Pi;
- else -- Y < 0.0
- return -Half_Pi;
- end if;
+ return Float_Type'Copy_Sign (Half_Pi, Y);
else
return Local_Atan (Y, X);
@@ -430,9 +423,7 @@ package body Ada.Numerics.Generic_Elementary_Functions is
if Cycle <= 0.0 then
raise Argument_Error;
- elsif X = 0.0
- and then Y = 0.0
- then
+ elsif X = 0.0 and then Y = 0.0 then
raise Argument_Error;
elsif Y = 0.0 then
@@ -443,11 +434,7 @@ package body Ada.Numerics.Generic_Elementary_Functions is
end if;
elsif X = 0.0 then
- if Y > 0.0 then
- return Cycle / 4.0;
- else -- Y < 0.0
- return -(Cycle / 4.0);
- end if;
+ return Float_Type'Copy_Sign (Cycle / 4.0, Y);
else
return Local_Atan (Y, X) * Cycle / Two_Pi;
@@ -460,6 +447,7 @@ package body Ada.Numerics.Generic_Elementary_Functions is
function Arctanh (X : Float_Type'Base) return Float_Type'Base is
A, B, D, A_Plus_1, A_From_1 : Float_Type'Base;
+
Mantissa : constant Integer := Float_Type'Base'Machine_Mantissa;
begin
@@ -491,9 +479,9 @@ package body Ada.Numerics.Generic_Elementary_Functions is
-- why is above line commented out ???
else
- -- Use several piecewise linear approximations.
- -- A is close to X, chosen so 1.0 + A, 1.0 - A, and X - A are exact.
- -- The two scalings remove the low-order bits of X.
+ -- Use several piecewise linear approximations. A is close to X,
+ -- chosen so 1.0 + A, 1.0 - A, and X - A are exact. The two scalings
+ -- remove the low-order bits of X.
A := Float_Type'Base'Scaling (
Float_Type'Base (Long_Long_Integer
@@ -505,16 +493,13 @@ package body Ada.Numerics.Generic_Elementary_Functions is
D := A_Plus_1 * A_From_1; -- 1 - A*A.
-- use one term of the series expansion:
- -- f (x + e) = f(x) + e * f'(x) + ..
+
+ -- f (x + e) = f(x) + e * f'(x) + ..
-- The derivative of Arctanh at A is 1/(1-A*A). Next term is
-- A*(B/D)**2 (if a quadratic approximation is ever needed).
return 0.5 * (Log (A_Plus_1) - Log (A_From_1)) + B / D;
-
- -- else
- -- return 0.5 * Log ((X + 1.0) / (1.0 - X));
- -- why are above lines commented out ???
end if;
end Arctanh;
@@ -541,8 +526,8 @@ package body Ada.Numerics.Generic_Elementary_Functions is
function Cos (X, Cycle : Float_Type'Base) return Float_Type'Base is
begin
- -- Just reuse the code for Sin. The potential small
- -- loss of speed is negligible with proper (front-end) inlining.
+ -- Just reuse the code for Sin. The potential small loss of speed is
+ -- negligible with proper (front-end) inlining.
return -Sin (abs X - Cycle * 0.25, Cycle);
end Cos;
@@ -705,8 +690,8 @@ package body Ada.Numerics.Generic_Elementary_Functions is
-- Deal with case of Exp returning IEEE infinity. If Machine_Overflows
-- is False, then we can just leave it as an infinity (and indeed we
- -- prefer to do so). But if Machine_Overflows is True, then we have
- -- to raise a Constraint_Error exception as required by the RM.
+ -- prefer to do so). But if Machine_Overflows is True, then we have to
+ -- raise a Constraint_Error exception as required by the RM.
if Float_Type'Machine_Overflows and then not R'Valid then
raise Constraint_Error;
@@ -721,9 +706,8 @@ package body Ada.Numerics.Generic_Elementary_Functions is
----------------
function Local_Atan
- (Y : Float_Type'Base;
- X : Float_Type'Base := 1.0)
- return Float_Type'Base
+ (Y : Float_Type'Base;
+ X : Float_Type'Base := 1.0) return Float_Type'Base
is
Z : Float_Type'Base;
Raw_Atan : Float_Type'Base;
@@ -741,18 +725,9 @@ package body Ada.Numerics.Generic_Elementary_Functions is
end if;
if X > 0.0 then
- if Y > 0.0 then
- return Raw_Atan;
- else -- Y < 0.0
- return -Raw_Atan;
- end if;
-
- else -- X < 0.0
- if Y > 0.0 then
- return Pi - Raw_Atan;
- else -- Y < 0.0
- return -(Pi - Raw_Atan);
- end if;
+ return Float_Type'Copy_Sign (Raw_Atan, Y);
+ else
+ return Float_Type'Copy_Sign (Pi - Raw_Atan, Y);
end if;
end Local_Atan;
@@ -821,27 +796,27 @@ package body Ada.Numerics.Generic_Elementary_Functions is
if Cycle <= 0.0 then
raise Argument_Error;
+ -- If X is zero, return it as the result, preserving the argument sign.
+ -- Is this test really needed on any machine ???
+
elsif X = 0.0 then
- -- Is this test really needed on any machine ???
return X;
end if;
T := Float_Type'Base'Remainder (X, Cycle);
- -- The following two reductions reduce the argument
- -- to the interval [-0.25 * Cycle, 0.25 * Cycle].
- -- This reduction is exact and is needed to prevent
- -- inaccuracy that may result if the sinus function
- -- a different (more accurate) value of Pi in its
- -- reduction than is used in the multiplication with Two_Pi.
+ -- The following two reductions reduce the argument to the interval
+ -- [-0.25 * Cycle, 0.25 * Cycle]. This reduction is exact and is needed
+ -- to prevent inaccuracy that may result if the sine function uses a
+ -- different (more accurate) value of Pi in its reduction than is used
+ -- in the multiplication with Two_Pi.
if abs T > 0.25 * Cycle then
T := 0.5 * Float_Type'Copy_Sign (Cycle, T) - T;
end if;
- -- Could test for 12.0 * abs T = Cycle, and return
- -- an exact value in those cases. It is not clear that
- -- this is worth the extra test though.
+ -- Could test for 12.0 * abs T = Cycle, and return an exact value in
+ -- those cases. It is not clear this is worth the extra test though.
return Float_Type'Base (Aux.Sin (Double (T / Cycle * Two_Pi)));
end Sin;
@@ -924,7 +899,6 @@ package body Ada.Numerics.Generic_Elementary_Functions is
elsif X = 0.0 then
return X;
-
end if;
return Float_Type'Base (Aux.Sqrt (Double (X)));
diff --git a/gcc/ada/a-rttiev.adb b/gcc/ada/a-rttiev.adb
index 55687ec8f6b..2fe78212c3d 100644
--- a/gcc/ada/a-rttiev.adb
+++ b/gcc/ada/a-rttiev.adb
@@ -75,9 +75,9 @@ package body Ada.Real_Time.Timing_Events is
-- with mutually exclusive access via Event_Queue_Lock.
procedure Remove_From_Queue (This : Any_Timing_Event);
- -- Remove the specified event pointer from the queue of pending events
- -- with mutually exclusive access via Event_Queue_Lock.
- -- This procedure is used by the client-side routines (Set_Handler, etc.).
+ -- Remove the specified event pointer from the queue of pending events with
+ -- mutually exclusive access via Event_Queue_Lock. This procedure is used
+ -- by the client-side routines (Set_Handler, etc.).
-----------
-- Timer --
@@ -94,6 +94,7 @@ package body Ada.Real_Time.Timing_Events is
-- selected is arbitrary and could be changed to suit the application
-- requirements. Obviously a shorter period would give better resolution
-- at the cost of more overhead.
+
begin
System.Tasking.Utilities.Make_Independent;
@@ -171,6 +172,7 @@ package body Ada.Real_Time.Timing_Events is
declare
Handler : constant Timing_Event_Handler := Next_Event.Handler;
+
begin
-- The first act is to clear the event, per D.15(13/2). Besides,
-- we cannot clear the handler pointer *after* invoking the
@@ -205,11 +207,17 @@ package body Ada.Real_Time.Timing_Events is
package By_Timeout is new Events.Generic_Sorting (Sooner);
-- Used to keep the events in ascending order by timeout value
+ ------------
+ -- Sooner --
+ ------------
+
function Sooner (Left, Right : Any_Timing_Event) return Boolean is
begin
return Left.Timeout < Right.Timeout;
end Sooner;
+ -- Start of processing for Insert_Into_Queue
+
begin
SSL.Abort_Defer.all;
@@ -236,12 +244,14 @@ package body Ada.Real_Time.Timing_Events is
procedure Remove_From_Queue (This : Any_Timing_Event) is
use Events;
Location : Cursor;
+
begin
SSL.Abort_Defer.all;
Write_Lock (Event_Queue_Lock'Access);
Location := All_Events.Find (This);
+
if Location /= No_Element then
All_Events.Delete (Location);
end if;
@@ -332,13 +342,9 @@ package body Ada.Real_Time.Timing_Events is
function Time_Of_Event (Event : Timing_Event) return Time is
begin
- -- RM D.15(18/2): Time_First must be returned if the event is not set
+ -- RM D.15(18/2): Time_First must be returned in the event is not set
- if Event.Handler = null then
- return Time_First;
- else
- return Event.Timeout;
- end if;
+ return (if Event.Handler = null then Time_First else Event.Timeout);
end Time_Of_Event;
--------------
diff --git a/gcc/ada/a-strhas.ads b/gcc/ada/a-strhas.ads
index 7d33bf7d019..c2574d1e996 100644
--- a/gcc/ada/a-strhas.ads
+++ b/gcc/ada/a-strhas.ads
@@ -13,6 +13,8 @@
-- --
------------------------------------------------------------------------------
+pragma Compiler_Unit;
+
with Ada.Containers;
function Ada.Strings.Hash (Key : String) return Containers.Hash_Type;
diff --git a/gcc/ada/a-ststio.adb b/gcc/ada/a-ststio.adb
index 79ee6cdfd5a..89273a89f4c 100644
--- a/gcc/ada/a-ststio.adb
+++ b/gcc/ada/a-ststio.adb
@@ -29,9 +29,10 @@
-- --
------------------------------------------------------------------------------
-with Interfaces.C_Streams; use Interfaces.C_Streams;
+with Interfaces.C_Streams; use Interfaces.C_Streams;
with System; use System;
+with System.Communication; use System.Communication;
with System.File_IO;
with System.Soft_Links;
with System.CRTL;
@@ -293,8 +294,8 @@ package body Ada.Streams.Stream_IO is
end if;
File.Index := File.Index + Count (Nread);
- Last := Item'First + Stream_Element_Offset (Nread) - 1;
File.Last_Op := Op_Read;
+ Last := Last_Index (Item'First, Nread);
end Read;
-- This version of Read is the primitive operation on the underlying
diff --git a/gcc/ada/a-tasatt.adb b/gcc/ada/a-tasatt.adb
index 11db89e4648..cb9fbab6e34 100644
--- a/gcc/ada/a-tasatt.adb
+++ b/gcc/ada/a-tasatt.adb
@@ -221,7 +221,6 @@
-- general use 'Unchecked_Access instead of 'Access as the package can be
-- instantiated from within a local context.
-with System.Error_Reporting;
with System.Storage_Elements;
with System.Task_Primitives.Operations;
with System.Tasking;
@@ -237,8 +236,7 @@ pragma Elaborate_All (System.Tasking.Task_Attributes);
package body Ada.Task_Attributes is
- use System.Error_Reporting,
- System.Tasking.Initialization,
+ use System.Tasking.Initialization,
System.Tasking,
System.Tasking.Task_Attributes,
Ada.Exceptions;
@@ -424,9 +422,6 @@ package body Ada.Task_Attributes is
end;
end if;
- pragma Assert (Shutdown ("Should never get here in Reference"));
- return null;
-
exception
when Tasking_Error | Program_Error =>
raise;
diff --git a/gcc/ada/a-textio.adb b/gcc/ada/a-textio.adb
index ceacfe5b127..0dd54632068 100644
--- a/gcc/ada/a-textio.adb
+++ b/gcc/ada/a-textio.adb
@@ -1659,8 +1659,8 @@ package body Ada.Text_IO is
begin
-- Don't allow change of mode for current file (RM A.10.2(5))
- if (File = Current_In or else
- File = Current_Out or else
+ if (File = Current_In or else
+ File = Current_Out or else
File = Current_Error)
and then To_FCB (Mode) /= File.Mode
then
diff --git a/gcc/ada/a-tiinio.adb b/gcc/ada/a-tiinio.adb
index 4a4eb520f91..f477dbf77a1 100644
--- a/gcc/ada/a-tiinio.adb
+++ b/gcc/ada/a-tiinio.adb
@@ -36,11 +36,10 @@ package body Ada.Text_IO.Integer_IO is
package Aux renames Ada.Text_IO.Integer_Aux;
Need_LLI : constant Boolean := Num'Base'Size > Integer'Size;
- -- Throughout this generic body, we distinguish between the case
- -- where type Integer is acceptable, and where a Long_Long_Integer
- -- is needed. This constant Boolean is used to test for these cases
- -- and since it is a constant, only the code for the relevant case
- -- will be included in the instance.
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Integer is acceptable, and where a Long_Long_Integer is needed. This
+ -- Boolean is used to test for these cases and since it is a constant, only
+ -- code for the relevant case will be included in the instance.
---------
-- Get --
diff --git a/gcc/ada/a-wtinio.adb b/gcc/ada/a-wtinio.adb
index 78f4bb8f3bb..507145f98e7 100644
--- a/gcc/ada/a-wtinio.adb
+++ b/gcc/ada/a-wtinio.adb
@@ -36,11 +36,10 @@ with System.WCh_WtS; use System.WCh_WtS;
package body Ada.Wide_Text_IO.Integer_IO is
Need_LLI : constant Boolean := Num'Base'Size > Integer'Size;
- -- Throughout this generic body, we distinguish between the case
- -- where type Integer is acceptable, and where a Long_Long_Integer
- -- is needed. This constant Boolean is used to test for these cases
- -- and since it is a constant, only the code for the relevant case
- -- will be included in the instance.
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Integer is acceptable, and where a Long_Long_Integer is needed. This
+ -- Boolean is used to test for these cases and since it is a constant, only
+ -- code for the relevant case will be included in the instance.
subtype TFT is Ada.Wide_Text_IO.File_Type;
-- File type required for calls to routines in Aux
diff --git a/gcc/ada/a-ztinio.adb b/gcc/ada/a-ztinio.adb
index ff36c4fd1a5..93e4d280960 100644
--- a/gcc/ada/a-ztinio.adb
+++ b/gcc/ada/a-ztinio.adb
@@ -36,11 +36,10 @@ with System.WCh_WtS; use System.WCh_WtS;
package body Ada.Wide_Wide_Text_IO.Integer_IO is
Need_LLI : constant Boolean := Num'Base'Size > Integer'Size;
- -- Throughout this generic body, we distinguish between the case
- -- where type Integer is acceptable, and where a Long_Long_Integer
- -- is needed. This constant Boolean is used to test for these cases
- -- and since it is a constant, only the code for the relevant case
- -- will be included in the instance.
+ -- Throughout this generic body, we distinguish between the case where type
+ -- Integer is acceptable, and where a Long_Long_Integer is needed. This
+ -- Boolean is used to test for these cases and since it is a constant, only
+ -- code for the relevant case will be included in the instance.
subtype TFT is Ada.Wide_Wide_Text_IO.File_Type;
-- File type required for calls to routines in Aux
diff --git a/gcc/ada/adadecode.c b/gcc/ada/adadecode.c
index 86216fcfe7d..43f14f12792 100644
--- a/gcc/ada/adadecode.c
+++ b/gcc/ada/adadecode.c
@@ -29,14 +29,26 @@
* *
****************************************************************************/
-#ifdef IN_GCC
+
+#if defined(IN_RTS)
+#include "tconfig.h"
+#include "tsystem.h"
+#elif defined(IN_GCC)
#include "config.h"
#include "system.h"
-#else
+#endif
+
#include <string.h>
#include <stdio.h>
#include <ctype.h>
+
+#include "adaint.h"
+
+#ifndef ISDIGIT
#define ISDIGIT(c) isdigit(c)
+#endif
+
+#ifndef PARMS
#define PARMS(ARGS) ARGS
#endif
@@ -237,6 +249,21 @@ __gnat_decode (const char *coded_name, char *ada_name, int verbose)
}
}
+ /* Check for nested subprogram ending in .nnnn and strip suffix. */
+ {
+ int last = strlen (ada_name) - 1;
+
+ while (ISDIGIT (ada_name[last]) && last > 0)
+ {
+ last--;
+ }
+
+ if (ada_name[last] == '.')
+ {
+ ada_name[last] = (char) 0;
+ }
+ }
+
/* Change all "__" to ".". */
{
int len = strlen (ada_name);
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index 5bce387d2bb..54b32232bb8 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -377,19 +377,21 @@ to_ptr32 (char **ptr64)
#define MAYBE_TO_PTR32(argv) argv
#endif
+const char ATTR_UNSET = 127;
+
void
__gnat_reset_attributes
(struct file_attributes* attr)
{
- attr->exists = -1;
+ attr->exists = ATTR_UNSET;
- attr->writable = -1;
- attr->readable = -1;
- attr->executable = -1;
+ attr->writable = ATTR_UNSET;
+ attr->readable = ATTR_UNSET;
+ attr->executable = ATTR_UNSET;
- attr->regular = -1;
- attr->symbolic_link = -1;
- attr->directory = -1;
+ attr->regular = ATTR_UNSET;
+ attr->symbolic_link = ATTR_UNSET;
+ attr->directory = ATTR_UNSET;
attr->timestamp = (OS_Time)-2;
attr->file_length = -1;
@@ -697,7 +699,7 @@ __gnat_os_filename (char *filename ATTRIBUTE_UNUSED,
char *encoding ATTRIBUTE_UNUSED, int *e_length)
{
#if defined (_WIN32) && ! defined (__vxworks) && ! defined (IS_CROSS)
- WS2SC (os_name, (TCHAR *)w_filename, (DWORD)o_length);
+ WS2SC (os_name, (TCHAR *)w_filename, (DWORD)*o_length);
*o_length = strlen (os_name);
strcpy (encoding, "encoding=utf8");
*e_length = strlen (encoding);
@@ -1799,7 +1801,7 @@ __gnat_stat (char *name, GNAT_STRUCT_STAT *statbuf)
int
__gnat_file_exists_attr (char* name, struct file_attributes* attr)
{
- if (attr->exists == -1) {
+ if (attr->exists == ATTR_UNSET) {
#ifdef __MINGW32__
/* On Windows do not use __gnat_stat() because of a bug in Microsoft
_stat() routine. When the system time-zone is set with a negative
@@ -1865,7 +1867,7 @@ __gnat_is_absolute_path (char *name, int length)
int
__gnat_is_regular_file_attr (char* name, struct file_attributes* attr)
{
- if (attr->regular == -1) {
+ if (attr->regular == ATTR_UNSET) {
__gnat_stat_to_attr (-1, name, attr);
}
@@ -1883,7 +1885,7 @@ __gnat_is_regular_file (char *name)
int
__gnat_is_directory_attr (char* name, struct file_attributes* attr)
{
- if (attr->directory == -1) {
+ if (attr->directory == ATTR_UNSET) {
__gnat_stat_to_attr (-1, name, attr);
}
@@ -2091,7 +2093,7 @@ __gnat_can_use_acl (TCHAR *wname)
int
__gnat_is_readable_file_attr (char* name, struct file_attributes* attr)
{
- if (attr->readable == -1) {
+ if (attr->readable == ATTR_UNSET) {
#if defined (_WIN32) && !defined (RTX)
TCHAR wname [GNAT_MAX_PATH_LEN + 2];
GENERIC_MAPPING GenericMapping;
@@ -2125,7 +2127,7 @@ __gnat_is_readable_file (char *name)
int
__gnat_is_writable_file_attr (char* name, struct file_attributes* attr)
{
- if (attr->writable == -1) {
+ if (attr->writable == ATTR_UNSET) {
#if defined (_WIN32) && !defined (RTX)
TCHAR wname [GNAT_MAX_PATH_LEN + 2];
GENERIC_MAPPING GenericMapping;
@@ -2163,7 +2165,7 @@ __gnat_is_writable_file (char *name)
int
__gnat_is_executable_file_attr (char* name, struct file_attributes* attr)
{
- if (attr->executable == -1) {
+ if (attr->executable == ATTR_UNSET) {
#if defined (_WIN32) && !defined (RTX)
TCHAR wname [GNAT_MAX_PATH_LEN + 2];
GENERIC_MAPPING GenericMapping;
@@ -2314,7 +2316,7 @@ __gnat_set_non_readable (char *name)
int
__gnat_is_symbolic_link_attr (char* name, struct file_attributes* attr)
{
- if (attr->symbolic_link == -1) {
+ if (attr->symbolic_link == ATTR_UNSET) {
#if defined (__vxworks) || defined (__nucleus__)
attr->symbolic_link = 0;
diff --git a/gcc/ada/adaint.h b/gcc/ada/adaint.h
index 0412ffbf808..7af079e35a9 100644
--- a/gcc/ada/adaint.h
+++ b/gcc/ada/adaint.h
@@ -74,15 +74,15 @@ typedef long OS_Time;
*/
struct file_attributes {
- short exists;
+ unsigned char exists;
- short writable;
- short readable;
- short executable;
+ unsigned char writable;
+ unsigned char readable;
+ unsigned char executable;
- short symbolic_link;
- short regular;
- short directory;
+ unsigned char symbolic_link;
+ unsigned char regular;
+ unsigned char directory;
OS_Time timestamp;
long file_length;
diff --git a/gcc/ada/bcheck.adb b/gcc/ada/bcheck.adb
index 18739e878ed..084ce199dda 100644
--- a/gcc/ada/bcheck.adb
+++ b/gcc/ada/bcheck.adb
@@ -191,6 +191,7 @@ package body Bcheck is
else
ALI_Path_Id :=
Osint.Full_Lib_File_Name (ALIs.Table (A).Afile);
+
if Osint.Is_Readonly_Library (ALI_Path_Id) then
if Tolerate_Consistency_Errors then
Error_Msg ("?{ should be recompiled");
diff --git a/gcc/ada/clean.adb b/gcc/ada/clean.adb
index b7bfd059869..978a5e7006f 100644
--- a/gcc/ada/clean.adb
+++ b/gcc/ada/clean.adb
@@ -1740,6 +1740,7 @@ package body Clean is
when 'e' =>
if Arg = "-eL" then
Follow_Links_For_Files := True;
+ Follow_Links_For_Dirs := True;
else
Bad_Argument;
diff --git a/gcc/ada/csinfo.adb b/gcc/ada/csinfo.adb
index 9d8b16b572c..be4e79f2567 100644
--- a/gcc/ada/csinfo.adb
+++ b/gcc/ada/csinfo.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -23,10 +23,10 @@
-- --
------------------------------------------------------------------------------
--- Program to check consistency of sinfo.ads and sinfo.adb. Checks that
--- field name usage is consistent and that assertion cross-reference lists
--- are correct, as well as making sure that all the comments on field name
--- usage are consistent.
+-- Program to check consistency of sinfo.ads and sinfo.adb. Checks that field
+-- name usage is consistent and that assertion cross-reference lists are
+-- correct, as well as making sure that all the comments on field name usage
+-- are consistent.
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Strings.Unbounded.Text_IO; use Ada.Strings.Unbounded.Text_IO;
@@ -296,6 +296,7 @@ begin
if Bad then
Put_Line ("fields conflict with standard fields for node " & Node);
+ raise Done;
end if;
end loop;
diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb
index f60a67b5b40..ca207b2e4d8 100644
--- a/gcc/ada/debug.adb
+++ b/gcc/ada/debug.adb
@@ -99,7 +99,7 @@ package body Debug is
-- d.f Inhibit folding of static expressions
-- d.g Enable conversion of raise into goto
-- d.h
- -- d.i
+ -- d.i Ignore Warnings pragmas
-- d.j
-- d.k
-- d.l Use Ada 95 semantics for limited function returns
@@ -513,6 +513,10 @@ package body Debug is
-- this if this debug flag is set. Later we will enable this more
-- generally by default.
+ -- d.i Ignore all occurrences of pragma Warnings in the sources. This can
+ -- be used in particular to disable Warnings (Off) to check if any of
+ -- these statements are inappropriate.
+
-- d.l Use Ada 95 semantics for limited function returns. This may be
-- used to work around the incompatibility introduced by AI-318-2.
-- It is useful only in -gnat05 mode.
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index 6330dec57f2..d4294728563 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -2098,7 +2098,11 @@ package Einfo is
-- Present in all entities. Set true for all entities declared in the
-- private part or body of a package. Also marks generic formals of a
-- formal package declared without a box. For library level entities,
--- this flag is set if the entity is not publicly visible.
+-- this flag is set if the entity is not publicly visible. This flag
+-- is reset when compiling the body of the package where the entity
+-- is declared, when compiling the private part or body of a public
+-- child unit, and when compiling a private child unit (see Install_
+-- Private_Declaration in sem_ch7).
-- Is_Hidden_Open_Scope (Flag171)
-- Present in all entities. Set true for a scope that contains the
@@ -2451,8 +2455,12 @@ package Einfo is
-- child unit, or if it is the descendent of a private child unit.
-- Is_Private_Primitive (Flag245)
--- Present in subprograms. Set if the first parameter of the subprogram
--- is of concurrent tagged type with a private view.
+-- Present in subprograms. Set if the operation is a primitive of a
+-- tagged type (procedure or function dispatching on result) whose
+-- full view has not been seen. Used in particular for primitive
+-- subprograms of a synchronized type declared between the two views
+-- of the type, so that the wrapper built for such a subprogram can
+-- be given the proper signature.
-- Is_Private_Type (synthesized)
-- Applies to all entities, true for private types and subtypes,
diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
index aa36a9ddaab..651b43d1122 100644
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -2848,13 +2848,35 @@ package body Errout is
Buffer_Remove ("type ");
end if;
- Set_Msg_Str ("access to subprogram with profile ");
+ if Is_Itype (Ent) then
+ declare
+ Assoc : constant Node_Id :=
+ Associated_Node_For_Itype (Ent);
+
+ begin
+ if Nkind (Assoc) in N_Subprogram_Specification then
+
+ -- Anonymous access to subprogram in a signature.
+ -- Indicate the enclosing subprogram.
+
+ Ent :=
+ Defining_Unit_Name
+ (Associated_Node_For_Itype (Ent));
+ Set_Msg_Str
+ ("access to subprogram declared in profile of ");
+
+ else
+ Set_Msg_Str ("access to subprogram with profile ");
+ end if;
+ end;
+ end if;
elsif Ekind (Ent) = E_Function then
Set_Msg_Str ("access to function ");
else
Set_Msg_Str ("access to procedure ");
end if;
+
exit;
-- Type is access to object, named or anonymous
diff --git a/gcc/ada/exp_atag.adb b/gcc/ada/exp_atag.adb
index 314258c3070..d5cdf0b79b7 100644
--- a/gcc/ada/exp_atag.adb
+++ b/gcc/ada/exp_atag.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Atree; use Atree;
with Einfo; use Einfo;
with Elists; use Elists;
with Exp_Util; use Exp_Util;
@@ -53,12 +54,14 @@ package body Exp_Atag is
-- To_Dispatch_Table_Ptr
-- (To_Address (Tag_Node) - Tag_Node.Prims_Ptr'Position);
- function Build_TSD (Loc : Source_Ptr; Tag_Node : Node_Id) return Node_Id;
+ function Build_TSD
+ (Loc : Source_Ptr;
+ Tag_Node_Addr : Node_Id) return Node_Id;
-- Build code that retrieves the address of the record containing the Type
-- Specific Data generated by GNAT.
--
-- Generate: To_Type_Specific_Data_Ptr
- -- (To_Addr_Ptr (To_Address (Tag) - Typeinfo_Offset).all);
+ -- (To_Addr_Ptr (Tag_Node_Addr - Typeinfo_Offset).all);
------------------------------------------------
-- Build_Common_Dispatching_Select_Statements --
@@ -140,39 +143,90 @@ package body Exp_Atag is
-- Build_CW_Membership --
-------------------------
- function Build_CW_Membership
+ procedure Build_CW_Membership
(Loc : Source_Ptr;
- Obj_Tag_Node : Node_Id;
- Typ_Tag_Node : Node_Id) return Node_Id
+ Obj_Tag_Node : in out Node_Id;
+ Typ_Tag_Node : Node_Id;
+ Related_Nod : Node_Id;
+ New_Node : out Node_Id)
is
- function Build_Pos return Node_Id;
- -- Generate TSD (Obj_Tag).Idepth - TSD (Typ_Tag).Idepth;
+ Tag_Addr : constant Entity_Id := Make_Defining_Identifier (Loc,
+ New_Internal_Name ('D'));
+ Obj_TSD : constant Entity_Id := Make_Defining_Identifier (Loc,
+ New_Internal_Name ('D'));
+ Typ_TSD : constant Entity_Id := Make_Defining_Identifier (Loc,
+ New_Internal_Name ('D'));
+ Index : constant Entity_Id := Make_Defining_Identifier (Loc,
+ New_Internal_Name ('D'));
- function Build_Pos return Node_Id is
- begin
- return
+ begin
+ -- Generate:
+
+ -- Tag_Addr : constant Tag := Address!(Obj_Tag);
+ -- Obj_TSD : constant Type_Specific_Data_Ptr
+ -- := Build_TSD (Tag_Addr);
+ -- Typ_TSD : constant Type_Specific_Data_Ptr
+ -- := Build_TSD (Address!(Typ_Tag));
+ -- Index : constant Integer := Obj_TSD.Idepth - Typ_TSD.Idepth
+ -- Index > 0 and then Obj_TSD.Tags_Table (Index) = Typ'Tag
+
+ Insert_Action (Related_Nod,
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Tag_Addr,
+ Constant_Present => True,
+ Object_Definition => New_Reference_To (RTE (RE_Address), Loc),
+ Expression => Unchecked_Convert_To
+ (RTE (RE_Address), Obj_Tag_Node)));
+
+ -- Unchecked_Convert_To relocates Obj_Tag_Node and therefore we must
+ -- update it.
+
+ Obj_Tag_Node := Expression (Expression (Parent (Tag_Addr)));
+
+ Insert_Action (Related_Nod,
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Obj_TSD,
+ Constant_Present => True,
+ Object_Definition => New_Reference_To
+ (RTE (RE_Type_Specific_Data_Ptr), Loc),
+ Expression => Build_TSD (Loc, New_Reference_To (Tag_Addr, Loc))));
+
+ Insert_Action (Related_Nod,
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Typ_TSD,
+ Constant_Present => True,
+ Object_Definition => New_Reference_To
+ (RTE (RE_Type_Specific_Data_Ptr), Loc),
+ Expression => Build_TSD (Loc,
+ Unchecked_Convert_To (RTE (RE_Address),
+ Typ_Tag_Node))));
+
+ Insert_Action (Related_Nod,
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Index,
+ Constant_Present => True,
+ Object_Definition => New_Occurrence_Of (Standard_Integer, Loc),
+ Expression =>
Make_Op_Subtract (Loc,
Left_Opnd =>
Make_Selected_Component (Loc,
- Prefix => Build_TSD (Loc, Duplicate_Subexpr (Obj_Tag_Node)),
- Selector_Name =>
- New_Reference_To (RTE_Record_Component (RE_Idepth), Loc)),
-
- Right_Opnd =>
- Make_Selected_Component (Loc,
- Prefix => Build_TSD (Loc, Duplicate_Subexpr (Typ_Tag_Node)),
+ Prefix => New_Reference_To (Obj_TSD, Loc),
Selector_Name =>
- New_Reference_To (RTE_Record_Component (RE_Idepth), Loc)));
- end Build_Pos;
+ New_Reference_To
+ (RTE_Record_Component (RE_Idepth), Loc)),
- -- Start of processing for Build_CW_Membership
+ Right_Opnd =>
+ Make_Selected_Component (Loc,
+ Prefix => New_Reference_To (Typ_TSD, Loc),
+ Selector_Name =>
+ New_Reference_To
+ (RTE_Record_Component (RE_Idepth), Loc)))));
- begin
- return
+ New_Node :=
Make_And_Then (Loc,
Left_Opnd =>
Make_Op_Ge (Loc,
- Left_Opnd => Build_Pos,
+ Left_Opnd => New_Occurrence_Of (Index, Loc),
Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
Right_Opnd =>
@@ -181,12 +235,12 @@ package body Exp_Atag is
Make_Indexed_Component (Loc,
Prefix =>
Make_Selected_Component (Loc,
- Prefix => Build_TSD (Loc, Obj_Tag_Node),
+ Prefix => New_Reference_To (Obj_TSD, Loc),
Selector_Name =>
New_Reference_To
(RTE_Record_Component (RE_Tags_Table), Loc)),
Expressions =>
- New_List (Build_Pos)),
+ New_List (New_Occurrence_Of (Index, Loc))),
Right_Opnd => Typ_Tag_Node));
end Build_CW_Membership;
@@ -197,7 +251,8 @@ package body Exp_Atag is
function Build_DT
(Loc : Source_Ptr;
- Tag_Node : Node_Id) return Node_Id is
+ Tag_Node : Node_Id) return Node_Id
+ is
begin
return
Make_Function_Call (Loc,
@@ -217,7 +272,9 @@ package body Exp_Atag is
begin
return
Make_Selected_Component (Loc,
- Prefix => Build_TSD (Loc, Tag_Node),
+ Prefix =>
+ Build_TSD (Loc,
+ Unchecked_Convert_To (RTE (RE_Address), Tag_Node)),
Selector_Name =>
New_Reference_To
(RTE_Record_Component (RE_Access_Level), Loc));
@@ -390,7 +447,9 @@ package body Exp_Atag is
begin
return
Make_Selected_Component (Loc,
- Prefix => Build_TSD (Loc, Tag_Node),
+ Prefix =>
+ Build_TSD (Loc,
+ Unchecked_Convert_To (RTE (RE_Address), Tag_Node)),
Selector_Name =>
New_Reference_To
(RTE_Record_Component (RE_Transportable), Loc));
@@ -529,7 +588,9 @@ package body Exp_Atag is
Make_Assignment_Statement (Loc,
Name =>
Make_Selected_Component (Loc,
- Prefix => Build_TSD (Loc, Tag_Node),
+ Prefix =>
+ Build_TSD (Loc,
+ Unchecked_Convert_To (RTE (RE_Address), Tag_Node)),
Selector_Name =>
New_Reference_To
(RTE_Record_Component (RE_Size_Func), Loc)),
@@ -572,7 +633,9 @@ package body Exp_Atag is
-- Build_TSD --
---------------
- function Build_TSD (Loc : Source_Ptr; Tag_Node : Node_Id) return Node_Id is
+ function Build_TSD
+ (Loc : Source_Ptr;
+ Tag_Node_Addr : Node_Id) return Node_Id is
begin
return
Unchecked_Convert_To (RTE (RE_Type_Specific_Data_Ptr),
@@ -590,9 +653,9 @@ package body Exp_Atag is
Chars => Name_Op_Subtract)),
Parameter_Associations => New_List (
- Unchecked_Convert_To (RTE (RE_Address), Tag_Node),
- New_Reference_To
- (RTE (RE_DT_Typeinfo_Ptr_Size), Loc))))));
+ Tag_Node_Addr,
+ New_Reference_To
+ (RTE (RE_DT_Typeinfo_Ptr_Size), Loc))))));
end Build_TSD;
end Exp_Atag;
diff --git a/gcc/ada/exp_atag.ads b/gcc/ada/exp_atag.ads
index 42ec4769c38..1fa243cf91f 100644
--- a/gcc/ada/exp_atag.ads
+++ b/gcc/ada/exp_atag.ads
@@ -41,18 +41,23 @@ package Exp_Atag is
-- Ada 2005 (AI-345): Generate statements that are common between timed,
-- asynchronous, and conditional select expansion.
- function Build_CW_Membership
+ procedure Build_CW_Membership
(Loc : Source_Ptr;
- Obj_Tag_Node : Node_Id;
- Typ_Tag_Node : Node_Id) return Node_Id;
+ Obj_Tag_Node : in out Node_Id;
+ Typ_Tag_Node : Node_Id;
+ Related_Nod : Node_Id;
+ New_Node : out Node_Id);
-- Build code that returns true if Obj_Tag is in Typ_Tag'Class. Each DT
-- has a table of ancestors and its inheritance level (Idepth). Obj is in
-- Typ'Class if Typ'Tag is found in the table of ancestors referenced by
-- Obj'Tag. Knowing the level of inheritance of both types, this can be
-- computed in constant time by the formula:
--
- -- TSD (Obj'tag).Tags_Table (TSD (Obj'tag).Idepth - TSD (Typ'tag).Idepth)
- -- = Typ'tag
+ -- Index := TSD (Obj'Tag).Idepth - TSD (Typ'Tag).Idepth;
+ -- Index > 0 and then TSD (Obj'Tag).Tags_Table (Index) = Typ'Tag
+ --
+ -- Related_Nod is the node where the implicit declaration of variable Index
+ -- is inserted. Obj_Tag_Node is relocated.
function Build_Get_Access_Level
(Loc : Source_Ptr;
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 9a91e2aa9bb..f61a4a5b47b 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -8104,6 +8104,11 @@ package body Exp_Ch3 is
elsif Restriction_Active (No_Finalization) then
null;
+ -- Skip these for CIL Value types, where finalization is not available
+
+ elsif Is_Value_Type (Tag_Typ) then
+ null;
+
elsif Etype (Tag_Typ) = Tag_Typ
or else Needs_Finalization (Tag_Typ)
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 6a7ea4fdb1b..4f0ef91a419 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -205,7 +205,10 @@ package body Exp_Ch4 is
-- its expression. If N is neither comparison nor a type conversion, the
-- call has no effect.
- function Tagged_Membership (N : Node_Id) return Node_Id;
+ procedure Tagged_Membership
+ (N : Node_Id;
+ SCIL_Node : out Node_Id;
+ Result : out Node_Id);
-- Construct the expression corresponding to the tagged membership test.
-- Deals with a second operand being (or not) a class-wide type.
@@ -4503,10 +4506,12 @@ package body Exp_Ch4 is
else
declare
- Typ : Entity_Id := Etype (Rop);
- Is_Acc : constant Boolean := Is_Access_Type (Typ);
- Obj : Node_Id := Lop;
- Cond : Node_Id := Empty;
+ Typ : Entity_Id := Etype (Rop);
+ Is_Acc : constant Boolean := Is_Access_Type (Typ);
+ Cond : Node_Id := Empty;
+ New_N : Node_Id;
+ Obj : Node_Id := Lop;
+ SCIL_Node : Node_Id;
begin
Remove_Side_Effects (Obj);
@@ -4521,8 +4526,19 @@ package body Exp_Ch4 is
-- normal tagged membership expansion is not what we want).
if Tagged_Type_Expansion then
- Rewrite (N, Tagged_Membership (N));
+ Tagged_Membership (N, SCIL_Node, New_N);
+ Rewrite (N, New_N);
Analyze_And_Resolve (N, Rtyp);
+
+ -- Update decoration of relocated node referenced by the
+ -- SCIL node.
+
+ if Generate_SCIL
+ and then Present (SCIL_Node)
+ then
+ Set_SCIL_Related_Node (SCIL_Node, N);
+ Insert_Action (N, SCIL_Node);
+ end if;
end if;
return;
@@ -5025,10 +5041,26 @@ package body Exp_Ch4 is
Expand_Boolean_Operator (N);
elsif Is_Boolean_Type (Etype (N)) then
- Adjust_Condition (Left_Opnd (N));
- Adjust_Condition (Right_Opnd (N));
- Set_Etype (N, Standard_Boolean);
- Adjust_Result_Type (N, Typ);
+
+ -- Replace AND by AND THEN if Short_Circuit_And_Or active and the
+ -- type is standard Boolean (do not mess with AND that uses a non-
+ -- standard Boolean type, because something strange is going on).
+
+ if Short_Circuit_And_Or and then Typ = Standard_Boolean then
+ Rewrite (N,
+ Make_And_Then (Sloc (N),
+ Left_Opnd => Relocate_Node (Left_Opnd (N)),
+ Right_Opnd => Relocate_Node (Right_Opnd (N))));
+ Analyze_And_Resolve (N, Typ);
+
+ -- Otherwise, adjust conditions
+
+ else
+ Adjust_Condition (Left_Opnd (N));
+ Adjust_Condition (Right_Opnd (N));
+ Set_Etype (N, Standard_Boolean);
+ Adjust_Result_Type (N, Typ);
+ end if;
end if;
end Expand_N_Op_And;
@@ -6913,10 +6945,26 @@ package body Exp_Ch4 is
Expand_Boolean_Operator (N);
elsif Is_Boolean_Type (Etype (N)) then
- Adjust_Condition (Left_Opnd (N));
- Adjust_Condition (Right_Opnd (N));
- Set_Etype (N, Standard_Boolean);
- Adjust_Result_Type (N, Typ);
+
+ -- Replace OR by OR ELSE if Short_Circuit_And_Or active and the
+ -- type is standard Boolean (do not mess with AND that uses a non-
+ -- standard Boolean type, because something strange is going on).
+
+ if Short_Circuit_And_Or and then Typ = Standard_Boolean then
+ Rewrite (N,
+ Make_Or_Else (Sloc (N),
+ Left_Opnd => Relocate_Node (Left_Opnd (N)),
+ Right_Opnd => Relocate_Node (Right_Opnd (N))));
+ Analyze_And_Resolve (N, Typ);
+
+ -- Otherwise, adjust conditions
+
+ else
+ Adjust_Condition (Left_Opnd (N));
+ Adjust_Condition (Right_Opnd (N));
+ Set_Etype (N, Standard_Boolean);
+ Adjust_Result_Type (N, Typ);
+ end if;
end if;
end Expand_N_Op_Or;
@@ -9825,16 +9873,23 @@ package body Exp_Ch4 is
-- table of abstract interface types plus the ancestor table contained in
-- the dispatch table pointed by Left_Expr.Tag for Typ'Tag
- function Tagged_Membership (N : Node_Id) return Node_Id is
+ procedure Tagged_Membership
+ (N : Node_Id;
+ SCIL_Node : out Node_Id;
+ Result : out Node_Id)
+ is
Left : constant Node_Id := Left_Opnd (N);
Right : constant Node_Id := Right_Opnd (N);
Loc : constant Source_Ptr := Sloc (N);
Left_Type : Entity_Id;
+ New_Node : Node_Id;
Right_Type : Entity_Id;
Obj_Tag : Node_Id;
begin
+ SCIL_Node := Empty;
+
-- Handle entities from the limited view
Left_Type := Available_View (Etype (Left));
@@ -9882,7 +9937,8 @@ package body Exp_Ch4 is
(Typ => Left_Type,
Iface => Etype (Right_Type))))
then
- return New_Reference_To (Standard_True, Loc);
+ Result := New_Reference_To (Standard_True, Loc);
+ return;
end if;
-- Ada 2005 (AI-251): Class-wide applied to interfaces
@@ -9899,10 +9955,11 @@ package body Exp_Ch4 is
if not RTE_Available (RE_IW_Membership) then
Error_Msg_CRT
("dynamic membership test on interface types", N);
- return Empty;
+ Result := Empty;
+ return;
end if;
- return
+ Result :=
Make_Function_Call (Loc,
Name => New_Occurrence_Of (RTE (RE_IW_Membership), Loc),
Parameter_Associations => New_List (
@@ -9917,14 +9974,27 @@ package body Exp_Ch4 is
-- Ada 95: Normal case
else
- return
- Build_CW_Membership (Loc,
- Obj_Tag_Node => Obj_Tag,
- Typ_Tag_Node =>
- New_Reference_To (
- Node (First_Elmt
- (Access_Disp_Table (Root_Type (Right_Type)))),
- Loc));
+ Build_CW_Membership (Loc,
+ Obj_Tag_Node => Obj_Tag,
+ Typ_Tag_Node =>
+ New_Reference_To (
+ Node (First_Elmt
+ (Access_Disp_Table (Root_Type (Right_Type)))),
+ Loc),
+ Related_Nod => N,
+ New_Node => New_Node);
+
+ -- Generate the SCIL node for this class-wide membership test.
+ -- Done here because the previous call to Build_CW_Membership
+ -- relocates Obj_Tag.
+
+ if Generate_SCIL then
+ SCIL_Node := Make_SCIL_Membership_Test (Sloc (N));
+ Set_SCIL_Entity (SCIL_Node, Etype (Right_Type));
+ Set_SCIL_Tag_Value (SCIL_Node, Obj_Tag);
+ end if;
+
+ Result := New_Node;
end if;
-- Right_Type is not a class-wide type
@@ -9933,10 +10003,10 @@ package body Exp_Ch4 is
-- No need to check the tag of the object if Right_Typ is abstract
if Is_Abstract_Type (Right_Type) then
- return New_Reference_To (Standard_False, Loc);
+ Result := New_Reference_To (Standard_False, Loc);
else
- return
+ Result :=
Make_Op_Eq (Loc,
Left_Opnd => Obj_Tag,
Right_Opnd =>
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 4a31187d9d1..fa74f6cc7ab 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -2314,9 +2314,9 @@ package body Exp_Ch6 is
end case;
- -- For allocators we pass the level of the execution of
- -- the called subprogram, which is one greater than the
- -- current scope level.
+ -- For allocators we pass the level of the execution of the
+ -- called subprogram, which is one greater than the current
+ -- scope level.
when N_Allocator =>
Add_Extra_Actual
@@ -2779,6 +2779,19 @@ package body Exp_Ch6 is
Unchecked_Convert_To (Parent_Typ,
Relocate_Node (Actual)));
+ -- If the relocated node is a function call then it
+ -- can be part of the expansion of the predefined
+ -- equality operator of a tagged type and we may
+ -- need to adjust its SCIL dispatching node.
+
+ if Generate_SCIL
+ and then Nkind (Actual) /= N_Null
+ and then Nkind (Expression (Actual))
+ = N_Function_Call
+ then
+ Adjust_SCIL_Node (Actual, Expression (Actual));
+ end if;
+
Analyze (Actual);
Resolve (Actual, Parent_Typ);
end if;
@@ -4489,6 +4502,21 @@ package body Exp_Ch6 is
Analyze (Prot_Decl);
Insert_Actions (N, Freeze_Entity (Prot_Id, Loc));
Set_Protected_Body_Subprogram (Subp, Prot_Id);
+
+ -- Create protected operation as well. Even though the operation
+ -- is only accessible within the body, it is possible to make it
+ -- available outside of the protected object by using 'Access to
+ -- provide a callback, so we build the protected version in all
+ -- cases.
+
+ Prot_Decl :=
+ Make_Subprogram_Declaration (Loc,
+ Specification =>
+ Build_Protected_Sub_Specification
+ (N, Scop, Protected_Mode));
+ Insert_Before (Prot_Bod, Prot_Decl);
+ Analyze (Prot_Decl);
+
Pop_Scope;
end if;
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index a4f6a66fd9b..880ae4e4cb9 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -3287,16 +3287,29 @@ package body Exp_Ch7 is
-- Start of processing for Needs_Finalization
begin
- -- Class-wide types must be treated as controlled because they may
- -- contain an extension that has controlled components
+ return
+
+ -- Class-wide types must be treated as controlled and therefore
+ -- requiring finalization (because they may be extended with an
+ -- extension that has controlled components.
+
+ (Is_Class_Wide_Type (T)
+
+ -- However, avoid treating class-wide types as controlled if
+ -- finalization is not available and in particular CIL value
+ -- types never have finalization).
- -- We can skip this if finalization is not available
+ and then not In_Finalization_Root (T)
+ and then not Restriction_Active (No_Finalization)
+ and then not Is_Value_Type (Etype (T)))
+
+ -- Controlled types always need finalization
- return (Is_Class_Wide_Type (T)
- and then not In_Finalization_Root (T)
- and then not Restriction_Active (No_Finalization))
or else Is_Controlled (T)
or else Has_Some_Controlled_Component (T)
+
+ -- For concurrent types, test the corresponding record type
+
or else (Is_Concurrent_Type (T)
and then Present (Corresponding_Record_Type (T))
and then Needs_Finalization (Corresponding_Record_Type (T)));
diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb
index 7fe20b37cad..c527bf6ef32 100644
--- a/gcc/ada/exp_ch9.adb
+++ b/gcc/ada/exp_ch9.adb
@@ -2180,6 +2180,58 @@ package body Exp_Ch9 is
is
Def : Node_Id;
Rec_Typ : Entity_Id;
+ procedure Scan_Declarations (L : List_Id);
+ -- Common processing for visible and private declarations
+ -- of a protected type.
+
+ procedure Scan_Declarations (L : List_Id) is
+ Decl : Node_Id;
+ Wrap_Decl : Node_Id;
+ Wrap_Spec : Node_Id;
+
+ begin
+ if No (L) then
+ return;
+ end if;
+
+ Decl := First (L);
+ while Present (Decl) loop
+ Wrap_Spec := Empty;
+
+ if Nkind (Decl) = N_Entry_Declaration
+ and then Ekind (Defining_Identifier (Decl)) = E_Entry
+ then
+ Wrap_Spec :=
+ Build_Wrapper_Spec
+ (Subp_Id => Defining_Identifier (Decl),
+ Obj_Typ => Rec_Typ,
+ Formals => Parameter_Specifications (Decl));
+
+ elsif Nkind (Decl) = N_Subprogram_Declaration then
+ Wrap_Spec :=
+ Build_Wrapper_Spec
+ (Subp_Id => Defining_Unit_Name (Specification (Decl)),
+ Obj_Typ => Rec_Typ,
+ Formals =>
+ Parameter_Specifications (Specification (Decl)));
+ end if;
+
+ if Present (Wrap_Spec) then
+ Wrap_Decl :=
+ Make_Subprogram_Declaration (Loc,
+ Specification => Wrap_Spec);
+
+ Insert_After (N, Wrap_Decl);
+ N := Wrap_Decl;
+
+ Analyze (Wrap_Decl);
+ end if;
+
+ Next (Decl);
+ end loop;
+ end Scan_Declarations;
+
+ -- start of processing for Build_Wrapper_Specs
begin
if Is_Protected_Type (Typ) then
@@ -2191,54 +2243,14 @@ package body Exp_Ch9 is
Rec_Typ := Corresponding_Record_Type (Typ);
-- Generate wrapper specs for a concurrent type which implements an
- -- interface and has visible entries and/or protected procedures.
+ -- interface. Operations in both the visible and private parts may
+ -- implement progenitor operations.
if Present (Interfaces (Rec_Typ))
and then Present (Def)
- and then Present (Visible_Declarations (Def))
then
- declare
- Decl : Node_Id;
- Wrap_Decl : Node_Id;
- Wrap_Spec : Node_Id;
-
- begin
- Decl := First (Visible_Declarations (Def));
- while Present (Decl) loop
- Wrap_Spec := Empty;
-
- if Nkind (Decl) = N_Entry_Declaration
- and then Ekind (Defining_Identifier (Decl)) = E_Entry
- then
- Wrap_Spec :=
- Build_Wrapper_Spec
- (Subp_Id => Defining_Identifier (Decl),
- Obj_Typ => Rec_Typ,
- Formals => Parameter_Specifications (Decl));
-
- elsif Nkind (Decl) = N_Subprogram_Declaration then
- Wrap_Spec :=
- Build_Wrapper_Spec
- (Subp_Id => Defining_Unit_Name (Specification (Decl)),
- Obj_Typ => Rec_Typ,
- Formals =>
- Parameter_Specifications (Specification (Decl)));
- end if;
-
- if Present (Wrap_Spec) then
- Wrap_Decl :=
- Make_Subprogram_Declaration (Loc,
- Specification => Wrap_Spec);
-
- Insert_After (N, Wrap_Decl);
- N := Wrap_Decl;
-
- Analyze (Wrap_Decl);
- end if;
-
- Next (Decl);
- end loop;
- end;
+ Scan_Declarations (Visible_Declarations (Def));
+ Scan_Declarations (Private_Declarations (Def));
end if;
end Build_Wrapper_Specs;
@@ -2551,6 +2563,70 @@ package body Exp_Ch9 is
end loop;
end Build_Master_Entity;
+ -----------------------------------------
+ -- Build_Private_Protected_Declaration --
+ -----------------------------------------
+
+ function Build_Private_Protected_Declaration
+ (N : Node_Id) return Entity_Id
+ is
+ Loc : constant Source_Ptr := Sloc (N);
+ Body_Id : constant Entity_Id := Defining_Entity (N);
+ Decl : Node_Id;
+ Plist : List_Id;
+ Formal : Entity_Id;
+ New_Spec : Node_Id;
+ Spec_Id : Entity_Id;
+
+ begin
+ Formal := First_Formal (Body_Id);
+
+ -- The protected operation always has at least one formal, namely the
+ -- object itself, but it is only placed in the parameter list if
+ -- expansion is enabled.
+
+ if Present (Formal) or else Expander_Active then
+ Plist := Copy_Parameter_List (Body_Id);
+ else
+ Plist := No_List;
+ end if;
+
+ if Nkind (Specification (N)) = N_Procedure_Specification then
+ New_Spec :=
+ Make_Procedure_Specification (Loc,
+ Defining_Unit_Name =>
+ Make_Defining_Identifier (Sloc (Body_Id),
+ Chars => Chars (Body_Id)),
+ Parameter_Specifications =>
+ Plist);
+ else
+ New_Spec :=
+ Make_Function_Specification (Loc,
+ Defining_Unit_Name =>
+ Make_Defining_Identifier (Sloc (Body_Id),
+ Chars => Chars (Body_Id)),
+ Parameter_Specifications =>
+ Plist,
+ Result_Definition =>
+ New_Occurrence_Of (Etype (Body_Id), Loc));
+ end if;
+
+ Decl := Make_Subprogram_Declaration (Loc, Specification => New_Spec);
+ Insert_Before (N, Decl);
+ Spec_Id := Defining_Unit_Name (New_Spec);
+
+ -- Indicate that the entity comes from source, to ensure that cross-
+ -- reference information is properly generated. The body itself is
+ -- rewritten during expansion, and the body entity will not appear in
+ -- calls to the operation.
+
+ Set_Comes_From_Source (Spec_Id, True);
+ Analyze (Decl);
+ Set_Has_Completion (Spec_Id);
+ Set_Convention (Spec_Id, Convention_Protected);
+ return Spec_Id;
+ end Build_Private_Protected_Declaration;
+
---------------------------
-- Build_Protected_Entry --
---------------------------
@@ -7182,7 +7258,6 @@ package body Exp_Ch9 is
New_Op_Body : Node_Id;
Num_Entries : Natural := 0;
Op_Body : Node_Id;
- Op_Decl : Node_Id;
Op_Id : Entity_Id;
Chain : Entity_Id := Empty;
@@ -7344,41 +7419,36 @@ package body Exp_Ch9 is
-- to an external caller. This is the common idiom in code
-- that uses the Ada 2005 Timing_Events package. As a result
-- we need to produce the protected body for both visible
- -- and private operations.
+ -- and private operations, as well as operations that only
+ -- have a body in the source, and for which we create a
+ -- declaration in the protected body itself.
if Present (Corresponding_Spec (Op_Body)) then
- Op_Decl :=
- Unit_Declaration_Node (Corresponding_Spec (Op_Body));
+ New_Op_Body :=
+ Build_Protected_Subprogram_Body (
+ Op_Body, Pid, Specification (New_Op_Body));
- if Nkind (Parent (Op_Decl)) =
- N_Protected_Definition
- then
- New_Op_Body :=
- Build_Protected_Subprogram_Body (
- Op_Body, Pid, Specification (New_Op_Body));
-
- Insert_After (Current_Node, New_Op_Body);
- Analyze (New_Op_Body);
+ Insert_After (Current_Node, New_Op_Body);
+ Analyze (New_Op_Body);
- Current_Node := New_Op_Body;
+ Current_Node := New_Op_Body;
- -- Generate an overriding primitive operation body for
- -- this subprogram if the protected type implements
- -- an interface.
+ -- Generate an overriding primitive operation body for
+ -- this subprogram if the protected type implements an
+ -- interface.
- if Ada_Version >= Ada_05
- and then Present (Interfaces (
- Corresponding_Record_Type (Pid)))
- then
- Disp_Op_Body :=
- Build_Dispatching_Subprogram_Body (
- Op_Body, Pid, New_Op_Body);
+ if Ada_Version >= Ada_05
+ and then
+ Present (Interfaces (Corresponding_Record_Type (Pid)))
+ then
+ Disp_Op_Body :=
+ Build_Dispatching_Subprogram_Body
+ (Op_Body, Pid, New_Op_Body);
- Insert_After (Current_Node, Disp_Op_Body);
- Analyze (Disp_Op_Body);
+ Insert_After (Current_Node, Disp_Op_Body);
+ Analyze (Disp_Op_Body);
- Current_Node := Disp_Op_Body;
- end if;
+ Current_Node := Disp_Op_Body;
end if;
end if;
end if;
@@ -7434,8 +7504,8 @@ package body Exp_Ch9 is
end loop;
-- Finally, create the body of the function that maps an entry index
- -- into the corresponding body index, except when there is no entry,
- -- or in a ravenscar-like profile.
+ -- into the corresponding body index, except when there is no entry, or
+ -- in a Ravenscar-like profile.
if Corresponding_Runtime_Package (Pid) =
System_Tasking_Protected_Objects_Entries
diff --git a/gcc/ada/exp_ch9.ads b/gcc/ada/exp_ch9.ads
index 61279d4eac5..22a27d6422e 100644
--- a/gcc/ada/exp_ch9.ads
+++ b/gcc/ada/exp_ch9.ads
@@ -81,6 +81,15 @@ package Exp_Ch9 is
-- object at the outer level, but it is much easier to generate one per
-- declarative part.
+ function Build_Private_Protected_Declaration (N : Node_Id) return Entity_Id;
+ -- A subprogram body without a previous spec that appears in a protected
+ -- body must be expanded separately to create a subprogram declaration
+ -- for it, in order to resolve internal calls to it from other protected
+ -- operations. It would seem that no locking version of the operation is
+ -- needed, but in fact, in Ada 2005 the subprogram may be used in a call-
+ -- back, and therefore a protected version of the operation must be
+ -- generated as well.
+
function Build_Protected_Sub_Specification
(N : Node_Id;
Prot_Typ : Entity_Id;
@@ -96,28 +105,28 @@ package Exp_Ch9 is
Name : Node_Id;
Rec : Node_Id;
External : Boolean := True);
- -- The node N is a subprogram or entry call to a protected subprogram.
- -- This procedure rewrites this call with the appropriate expansion.
- -- Name is the subprogram, and Rec is the record corresponding to the
- -- protected object. External is False if the call is to another
- -- protected subprogram within the same object.
+ -- The node N is a subprogram or entry call to a protected subprogram. This
+ -- procedure rewrites this call with the appropriate expansion. Name is the
+ -- subprogram, and Rec is the record corresponding to the protected object.
+ -- External is False if the call is to another protected subprogram within
+ -- the same object.
procedure Build_Task_Activation_Call (N : Node_Id);
- -- This procedure is called for constructs that can be task activators
- -- i.e. task bodies, subprogram bodies, package bodies and blocks. If
- -- the construct is a task activator (as indicated by the non-empty
- -- setting of Activation_Chain_Entity, either in the construct, or, in
- -- the case of a package body, in its associated package spec), then
- -- a call to Activate_Tasks with this entity as the single parameter
- -- is inserted at the start of the statements of the activator.
+ -- This procedure is called for constructs that can be task activators,
+ -- i.e. task bodies, subprogram bodies, package bodies and blocks. If the
+ -- construct is a task activator (as indicated by the non-empty setting of
+ -- Activation_Chain_Entity, either in the construct, or, in the case of a
+ -- package body, in its associated package spec), then a call to
+ -- Activate_Tasks with this entity as the single parameter is inserted at
+ -- the start of the statements of the activator.
procedure Build_Task_Allocate_Block
(Actions : List_Id;
N : Node_Id;
Args : List_Id);
- -- This routine is used in the case of allocators where the designated
- -- type is a task or contains tasks. In this case, the normal initialize
- -- call is replaced by:
+ -- This routine is used in the case of allocators where the designated type
+ -- is a task or contains tasks. In this case, the normal initialize call
+ -- is replaced by:
--
-- blockname : label;
-- blockname : declare
@@ -137,10 +146,10 @@ package Exp_Ch9 is
--
-- to get the task or tasks created and initialized. The expunge call
-- ensures that any tasks that get created but not activated due to an
- -- exception are properly expunged (it has no effect in the normal case)
- -- The argument N is the allocator, and Args is the list of arguments
- -- for the initialization call, constructed by the caller, which uses
- -- the Master_Id of the access type as the _Master parameter, and _Chain
+ -- exception are properly expunged (it has no effect in the normal case).
+ -- The argument N is the allocator, and Args is the list of arguments for
+ -- the initialization call, constructed by the caller, which uses the
+ -- Master_Id of the access type as the _Master parameter, and _Chain
-- (defined above) as the _Chain parameter.
procedure Build_Task_Allocate_Block_With_Init_Stmts
@@ -190,28 +199,28 @@ package Exp_Ch9 is
Index : Node_Id;
Ttyp : Entity_Id)
return Node_Id;
- -- Returns an expression to compute a task entry index given the name
- -- of the entry or entry family. For the case of a task entry family,
- -- the Index parameter contains the expression for the subscript.
- -- Ttyp is the task type.
+ -- Returns an expression to compute a task entry index given the name of
+ -- the entry or entry family. For the case of a task entry family, the
+ -- Index parameter contains the expression for the subscript. Ttyp is the
+ -- task type.
procedure Establish_Task_Master (N : Node_Id);
-- Given a subprogram body, or a block statement, or a task body, this
- -- procedure makes the necessary transformations required of a task
- -- master (add Enter_Master call at start, and establish a cleanup
- -- routine to make sure Complete_Master is called on exit).
+ -- procedure makes the necessary transformations required of a task master
+ -- (add Enter_Master call at start, and establish a cleanup routine to make
+ -- sure Complete_Master is called on exit).
procedure Expand_Access_Protected_Subprogram_Type (N : Node_Id);
-- Build Equivalent_Type for an Access_To_Protected_Subprogram.
- -- Equivalent_Type is a record type with two components: a pointer
- -- to the protected object, and a pointer to the operation itself.
+ -- Equivalent_Type is a record type with two components: a pointer to the
+ -- protected object, and a pointer to the operation itself.
procedure Expand_Accept_Declarations (N : Node_Id; Ent : Entity_Id);
- -- Expand declarations required for accept statement. See bodies of
- -- both Expand_Accept_Declarations and Expand_N_Accept_Statement for
- -- full details of the nature and use of these declarations, which
- -- are inserted immediately before the accept node N. The second
- -- argument is the entity for the corresponding entry.
+ -- Expand declarations required for accept statement. See bodies of both
+ -- Expand_Accept_Declarations and Expand_N_Accept_Statement for full
+ -- details of the nature and use of these declarations, which are inserted
+ -- immediately before the accept node N. The second argument is the entity
+ -- for the corresponding entry.
procedure Expand_Entry_Barrier (N : Node_Id; Ent : Entity_Id);
-- Expand the entry barrier into a function. This is called directly
diff --git a/gcc/ada/exp_intr.adb b/gcc/ada/exp_intr.adb
index 8f41a63c470..da6cf5a988c 100644
--- a/gcc/ada/exp_intr.adb
+++ b/gcc/ada/exp_intr.adb
@@ -234,19 +234,28 @@ package body Exp_Intr is
-- the tag in the table of ancestor tags.
elsif not Is_Interface (Result_Typ) then
- Insert_Action (N,
- Make_Implicit_If_Statement (N,
- Condition =>
- Make_Op_Not (Loc,
- Build_CW_Membership (Loc,
- Obj_Tag_Node => Duplicate_Subexpr (Tag_Arg),
- Typ_Tag_Node =>
- New_Reference_To (
- Node (First_Elmt (Access_Disp_Table (
- Root_Type (Result_Typ)))), Loc))),
- Then_Statements =>
- New_List (Make_Raise_Statement (Loc,
- New_Occurrence_Of (RTE (RE_Tag_Error), Loc)))));
+ declare
+ Obj_Tag_Node : Node_Id := Duplicate_Subexpr (Tag_Arg);
+ CW_Test_Node : Node_Id;
+
+ begin
+ Build_CW_Membership (Loc,
+ Obj_Tag_Node => Obj_Tag_Node,
+ Typ_Tag_Node =>
+ New_Reference_To (
+ Node (First_Elmt (Access_Disp_Table (
+ Root_Type (Result_Typ)))), Loc),
+ Related_Nod => N,
+ New_Node => CW_Test_Node);
+
+ Insert_Action (N,
+ Make_Implicit_If_Statement (N,
+ Condition =>
+ Make_Op_Not (Loc, CW_Test_Node),
+ Then_Statements =>
+ New_List (Make_Raise_Statement (Loc,
+ New_Occurrence_Of (RTE (RE_Tag_Error), Loc)))));
+ end;
-- Call IW_Membership test if the Result_Type is an abstract interface
-- to look for the tag in the table of interface tags.
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 535ec4ca16e..564c11b6613 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -2761,6 +2761,7 @@ package body Exp_Util is
N_SCIL_Dispatch_Table_Object_Init |
N_SCIL_Dispatch_Table_Tag_Init |
N_SCIL_Dispatching_Call |
+ N_SCIL_Membership_Test |
N_SCIL_Tag_Init |
N_Selected_Component |
N_Signed_Integer_Type_Definition |
@@ -3411,17 +3412,49 @@ package body Exp_Util is
--------------------
procedure Kill_Dead_Code (N : Node_Id; Warn : Boolean := False) is
+ W : Boolean := Warn;
+ -- Set False if warnings suppressed
+
begin
if Present (N) then
Remove_Warning_Messages (N);
- if Warn then
- Error_Msg_F
- ("?this code can never be executed and has been deleted!", N);
+ -- Generate warning if appropriate
+
+ if W then
+
+ -- We suppress the warning if this code is under control of an
+ -- if statement, whose condition is a simple identifier, and
+ -- either we are in an instance, or warnings off is set for this
+ -- identifier. The reason for killing it in the instance case is
+ -- that it is common and reasonable for code to be deleted in
+ -- instances for various reasons.
+
+ if Nkind (Parent (N)) = N_If_Statement then
+ declare
+ C : constant Node_Id := Condition (Parent (N));
+ begin
+ if Nkind (C) = N_Identifier
+ and then
+ (In_Instance
+ or else (Present (Entity (C))
+ and then Has_Warnings_Off (Entity (C))))
+ then
+ W := False;
+ end if;
+ end;
+ end if;
+
+ -- Generate warning if not suppressed
+
+ if W then
+ Error_Msg_F
+ ("?this code can never be executed and has been deleted!", N);
+ end if;
end if;
-- Recurse into block statements and bodies to process declarations
- -- and statements
+ -- and statements.
if Nkind (N) = N_Block_Statement
or else Nkind (N) = N_Subprogram_Body
diff --git a/gcc/ada/expect.c b/gcc/ada/expect.c
index c11a3aa8652..4f0f73fd15b 100644
--- a/gcc/ada/expect.c
+++ b/gcc/ada/expect.c
@@ -78,12 +78,11 @@
#ifdef _WIN32
-/* We need functionality available only starting with Windows XP */
-#define _WIN32_WINNT 0x0501
-
#include <windows.h>
#include <process.h>
#include <signal.h>
+#include <io.h>
+#include "mingw32.h"
void
__gnat_kill (int pid, int sig, int close)
@@ -144,8 +143,8 @@ __gnat_pipe (int *fd)
HANDLE read, write;
CreatePipe (&read, &write, NULL, 0);
- fd[0]=_open_osfhandle ((long)read, 0);
- fd[1]=_open_osfhandle ((long)write, 0);
+ fd[0]=_open_osfhandle ((intptr_t)read, 0);
+ fd[1]=_open_osfhandle ((intptr_t)write, 0);
return 0; /* always success */
}
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 85206f7ae8b..7f0f7863824 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -2535,6 +2535,8 @@ package body Freeze is
and then not Has_Warnings_Off (F_Type)
and then not Has_Warnings_Off (Formal)
then
+ -- Qualify mention of formals with subprogram name
+
Error_Msg_Qual_Level := 1;
-- Check suspicious use of fat C pointer
@@ -2543,8 +2545,8 @@ package body Freeze is
and then Esize (F_Type) > Ttypes.System_Address_Size
then
Error_Msg_N
- ("?type of & does not correspond "
- & "to C pointer!", Formal);
+ ("?type of & does not correspond to C pointer!",
+ Formal);
-- Check suspicious return of boolean
@@ -2552,10 +2554,13 @@ package body Freeze is
and then Convention (F_Type) = Convention_Ada
and then not Has_Warnings_Off (F_Type)
and then not Has_Size_Clause (F_Type)
+ and then VM_Target = No_VM
then
Error_Msg_N
- ("?& is an 8-bit Ada Boolean, "
- & "use char in C!", Formal);
+ ("& is an 8-bit Ada Boolean?", Formal);
+ Error_Msg_N
+ ("\use appropriate corresponding type in C "
+ & "(e.g. char)?", Formal);
-- Check suspicious tagged type
@@ -2584,6 +2589,8 @@ package body Freeze is
Formal, F_Type);
end if;
+ -- Turn off name qualification after message output
+
Error_Msg_Qual_Level := 0;
end if;
@@ -2595,6 +2602,11 @@ package body Freeze is
and then Is_Array_Type (F_Type)
and then not Is_Constrained (F_Type)
and then Warn_On_Export_Import
+
+ -- Exclude VM case, since both .NET and JVM can handle
+ -- unconstrained arrays without a problem.
+
+ and then VM_Target = No_VM
then
Error_Msg_Qual_Level := 1;
@@ -2676,13 +2688,22 @@ package body Freeze is
elsif Root_Type (R_Type) = Standard_Boolean
and then Convention (R_Type) = Convention_Ada
+ and then VM_Target = No_VM
and then not Has_Warnings_Off (E)
and then not Has_Warnings_Off (R_Type)
and then not Has_Size_Clause (R_Type)
then
- Error_Msg_N
- ("?return type of & is an 8-bit "
- & "Ada Boolean, use char in C!", E);
+ declare
+ N : constant Node_Id :=
+ Result_Definition (Declaration_Node (E));
+ begin
+ Error_Msg_NE
+ ("return type of & is an 8-bit Ada Boolean?",
+ N, E);
+ Error_Msg_NE
+ ("\use appropriate corresponding type in C "
+ & "(e.g. char)?", N, E);
+ end;
-- Check suspicious return tagged type
diff --git a/gcc/ada/frontend.adb b/gcc/ada/frontend.adb
index 3285acc401c..89746b88035 100644
--- a/gcc/ada/frontend.adb
+++ b/gcc/ada/frontend.adb
@@ -47,6 +47,7 @@ with Prepcomp;
with Restrict; use Restrict;
with Rident; use Rident;
with Rtsfind; use Rtsfind;
+with Snames; use Snames;
with Sprint;
with Scn; use Scn;
with Sem; use Sem;
@@ -381,6 +382,29 @@ begin
Sprint.Source_Dump;
+ -- Check again for configuration pragmas that appear in the context of
+ -- the main unit. These pragmas only affect the main unit, and the
+ -- corresponding flag is reset after each call to Semantics, but they
+ -- may affect the generated ali for the unit, and therefore the flag
+ -- must be set properly after compilation. Currently we only check for
+ -- Initialize_Scalars, but others should be checked: as well???
+
+ declare
+ Item : Node_Id;
+
+ begin
+ Item := First (Context_Items (Cunit (Main_Unit)));
+ while Present (Item) loop
+ if Nkind (Item) = N_Pragma
+ and then Pragma_Name (Item) = Name_Initialize_Scalars
+ then
+ Initialize_Scalars := True;
+ end if;
+
+ Next (Item);
+ end loop;
+ end;
+
-- If a mapping file has been specified by a -gnatem switch, update
-- it if there has been some sources that were not in the mappings.
diff --git a/gcc/ada/g-alleve.adb b/gcc/ada/g-alleve.adb
index 3443344fe33..39d0b7240db 100644
--- a/gcc/ada/g-alleve.adb
+++ b/gcc/ada/g-alleve.adb
@@ -376,11 +376,8 @@ package body GNAT.Altivec.Low_Level_Vectors is
begin
for K in Varray_Type'Range loop
- if A (K) /= Component_Type'First then
- D (K) := abs (A (K));
- else
- D (K) := Component_Type'First;
- end if;
+ D (K) := (if A (K) /= Component_Type'First
+ then abs (A (K)) else Component_Type'First);
end loop;
return D;
@@ -443,11 +440,7 @@ package body GNAT.Altivec.Low_Level_Vectors is
begin
for J in Varray_Type'Range loop
- if A (J) > B (J) then
- D (J) := Bool_True;
- else
- D (J) := Bool_False;
- end if;
+ D (J) := (if A (J) > B (J) then Bool_True else Bool_False);
end loop;
return D;
@@ -489,11 +482,7 @@ package body GNAT.Altivec.Low_Level_Vectors is
begin
for J in Varray_Type'Range loop
- if A (J) > B (J) then
- D (J) := A (J);
- else
- D (J) := B (J);
- end if;
+ D (J) := (if A (J) > B (J) then A (J) else B (J));
end loop;
return D;
@@ -545,11 +534,7 @@ package body GNAT.Altivec.Low_Level_Vectors is
begin
for J in Varray_Type'Range loop
- if A (J) < B (J) then
- D (J) := A (J);
- else
- D (J) := B (J);
- end if;
+ D (J) := (if A (J) < B (J) then A (J) else B (J));
end loop;
return D;
@@ -971,11 +956,7 @@ package body GNAT.Altivec.Low_Level_Vectors is
begin
for J in Varray_Type'Range loop
- if A (J) = B (J) then
- D (J) := Bool_True;
- else
- D (J) := Bool_False;
- end if;
+ D (J) := (if A (J) = B (J) then Bool_True else Bool_False);
end loop;
return D;
@@ -992,11 +973,7 @@ package body GNAT.Altivec.Low_Level_Vectors is
D : Varray_Type;
begin
for J in Varray_Type'Range loop
- if A (J) > B (J) then
- D (J) := Bool_True;
- else
- D (J) := Bool_False;
- end if;
+ D (J) := (if A (J) > B (J) then Bool_True else Bool_False);
end loop;
return D;
@@ -1011,11 +988,7 @@ package body GNAT.Altivec.Low_Level_Vectors is
begin
for J in Varray_Type'Range loop
- if A (J) > B (J) then
- D (J) := A (J);
- else
- D (J) := B (J);
- end if;
+ D (J) := (if A (J) > B (J) then A (J) else B (J));
end loop;
return D;
@@ -1030,11 +1003,7 @@ package body GNAT.Altivec.Low_Level_Vectors is
begin
for J in Varray_Type'Range loop
- if A (J) < B (J) then
- D (J) := A (J);
- else
- D (J) := B (J);
- end if;
+ D (J) := (if A (J) < B (J) then A (J) else B (J));
end loop;
return D;
@@ -1248,17 +1217,15 @@ package body GNAT.Altivec.Low_Level_Vectors is
begin
for J in 0 .. N - 1 loop
- if Use_Even_Components then
- Offset := Index_Type (2 * J + Integer (Index_Type'First));
- else
- Offset := Index_Type (2 * J + 1 + Integer (Index_Type'First));
- end if;
+ Offset :=
+ Index_Type ((if Use_Even_Components then 2 * J else 2 * J + 1) +
+ Integer (Index_Type'First));
Double_Offset :=
Double_Index_Type (J + Integer (Double_Index_Type'First));
D (Double_Offset) :=
- Double_Component_Type (A (Offset))
- * Double_Component_Type (B (Offset));
+ Double_Component_Type (A (Offset)) *
+ Double_Component_Type (B (Offset));
end loop;
return D;
@@ -1418,17 +1385,15 @@ package body GNAT.Altivec.Low_Level_Vectors is
begin
for J in 0 .. N - 1 loop
- if Use_Even_Components then
- Offset := Index_Type (2 * J + Integer (Index_Type'First));
- else
- Offset := Index_Type (2 * J + 1 + Integer (Index_Type'First));
- end if;
+ Offset :=
+ Index_Type ((if Use_Even_Components then 2 * J else 2 * J + 1) +
+ Integer (Index_Type'First));
Double_Offset :=
Double_Index_Type (J + Integer (Double_Index_Type'First));
D (Double_Offset) :=
- Double_Component_Type (A (Offset))
- * Double_Component_Type (B (Offset));
+ Double_Component_Type (A (Offset)) *
+ Double_Component_Type (B (Offset));
end loop;
return D;
@@ -1620,11 +1585,7 @@ package body GNAT.Altivec.Low_Level_Vectors is
if (Bits (VSCR, NJ_POS, NJ_POS) = 1)
and then abs (X) < 2.0 ** (-126)
then
- if X < 0.0 then
- D := -0.0;
- else
- D := 0.0;
- end if;
+ D := (if X < 0.0 then -0.0 else +0.0);
else
D := X;
end if;
@@ -1648,17 +1609,18 @@ package body GNAT.Altivec.Low_Level_Vectors is
function Rnd_To_FPI_Near (X : F64) return F64 is
Result : F64;
Ceiling : F64;
+
begin
Result := F64 (SI64 (X));
if (F64'Ceiling (X) - X) = (X + 1.0 - F64'Ceiling (X)) then
+
-- Round to even
+
Ceiling := F64'Ceiling (X);
- if Rnd_To_FPI_Trunc (Ceiling / 2.0) * 2.0 = Ceiling then
- Result := Ceiling;
- else
- Result := Ceiling - 1.0;
- end if;
+ Result :=
+ (if Rnd_To_FPI_Trunc (Ceiling / 2.0) * 2.0 = Ceiling
+ then Ceiling else Ceiling - 1.0);
end if;
return Result;
@@ -2111,14 +2073,9 @@ package body GNAT.Altivec.Low_Level_Vectors is
begin
for J in Varray_unsigned_int'Range loop
- Addition_Result :=
- UI64 (VA.Values (J)) + UI64 (VB.Values (J));
-
- if Addition_Result > UI64 (unsigned_int'Last) then
- D.Values (J) := 1;
- else
- D.Values (J) := 0;
- end if;
+ Addition_Result := UI64 (VA.Values (J)) + UI64 (VB.Values (J));
+ D.Values (J) :=
+ (if Addition_Result > UI64 (unsigned_int'Last) then 1 else 0);
end loop;
return To_LL_VSI (To_Vector (D));
@@ -2374,19 +2331,15 @@ package body GNAT.Altivec.Low_Level_Vectors is
D.Values (K) := Write_Bit (D.Values (K), 1, 1);
else
- if NJ_Truncate (VA.Values (J))
- <= NJ_Truncate (VB.Values (J)) then
- D.Values (K) := Write_Bit (D.Values (K), 0, 0);
- else
- D.Values (K) := Write_Bit (D.Values (K), 0, 1);
- end if;
-
- if NJ_Truncate (VA.Values (J))
- >= -NJ_Truncate (VB.Values (J)) then
- D.Values (K) := Write_Bit (D.Values (K), 1, 0);
- else
- D.Values (K) := Write_Bit (D.Values (K), 1, 1);
- end if;
+ D.Values (K) :=
+ (if NJ_Truncate (VA.Values (J)) <= NJ_Truncate (VB.Values (J))
+ then Write_Bit (D.Values (K), 0, 0)
+ else Write_Bit (D.Values (K), 0, 1));
+
+ D.Values (K) :=
+ (if NJ_Truncate (VA.Values (J)) >= -NJ_Truncate (VB.Values (J))
+ then Write_Bit (D.Values (K), 1, 0)
+ else Write_Bit (D.Values (K), 1, 1));
end if;
end loop;
@@ -2441,17 +2394,11 @@ package body GNAT.Altivec.Low_Level_Vectors is
VA : constant VF_View := To_View (A);
VB : constant VF_View := To_View (B);
D : VUI_View;
- K : Vint_Range;
begin
for J in Varray_float'Range loop
- K := Vint_Range (J);
-
- if VA.Values (J) = VB.Values (J) then
- D.Values (K) := unsigned_int'Last;
- else
- D.Values (K) := 0;
- end if;
+ D.Values (Vint_Range (J)) :=
+ (if VA.Values (J) = VB.Values (J) then unsigned_int'Last else 0);
end loop;
return To_LL_VSI (To_Vector (D));
@@ -2465,17 +2412,12 @@ package body GNAT.Altivec.Low_Level_Vectors is
VA : constant VF_View := To_View (A);
VB : constant VF_View := To_View (B);
D : VSI_View;
- K : Vint_Range;
begin
for J in Varray_float'Range loop
- K := Vint_Range (J);
-
- if VA.Values (J) >= VB.Values (J) then
- D.Values (K) := Signed_Bool_True;
- else
- D.Values (K) := Signed_Bool_False;
- end if;
+ D.Values (Vint_Range (J)) :=
+ (if VA.Values (J) >= VB.Values (J) then Signed_Bool_True
+ else Signed_Bool_False);
end loop;
return To_Vector (D);
@@ -2567,18 +2509,12 @@ package body GNAT.Altivec.Low_Level_Vectors is
VA : constant VF_View := To_View (A);
VB : constant VF_View := To_View (B);
D : VSI_View;
- K : Vint_Range;
begin
for J in Varray_float'Range loop
- K := Vint_Range (J);
-
- if NJ_Truncate (VA.Values (J))
- > NJ_Truncate (VB.Values (J)) then
- D.Values (K) := Signed_Bool_True;
- else
- D.Values (K) := Signed_Bool_False;
- end if;
+ D.Values (Vint_Range (J)) :=
+ (if NJ_Truncate (VA.Values (J)) > NJ_Truncate (VB.Values (J))
+ then Signed_Bool_True else Signed_Bool_False);
end loop;
return To_Vector (D);
@@ -3069,11 +3005,8 @@ package body GNAT.Altivec.Low_Level_Vectors is
begin
for J in Varray_float'Range loop
- if VA.Values (J) > VB.Values (J) then
- D.Values (J) := VA.Values (J);
- else
- D.Values (J) := VB.Values (J);
- end if;
+ D.Values (J) := (if VA.Values (J) > VB.Values (J) then VA.Values (J)
+ else VB.Values (J));
end loop;
return To_Vector (D);
@@ -3186,11 +3119,8 @@ package body GNAT.Altivec.Low_Level_Vectors is
begin
for J in Varray_float'Range loop
- if VA.Values (J) < VB.Values (J) then
- D.Values (J) := VA.Values (J);
- else
- D.Values (J) := VB.Values (J);
- end if;
+ D.Values (J) := (if VA.Values (J) < VB.Values (J) then VA.Values (J)
+ else VB.Values (J));
end loop;
return To_Vector (D);
@@ -3924,12 +3854,9 @@ package body GNAT.Altivec.Low_Level_Vectors is
for N in Vchar_Range'Range loop
J := Vchar_Range (Integer (Bits (VC.Values (N), 4, 7))
+ Integer (Vchar_Range'First));
-
- if Bits (VC.Values (N), 3, 3) = 0 then
- D.Values (N) := VA.Values (J);
- else
- D.Values (N) := VB.Values (J);
- end if;
+ D.Values (N) :=
+ (if Bits (VC.Values (N), 3, 3) = 0 then VA.Values (J)
+ else VB.Values (J));
end loop;
return To_LL_VSI (To_Vector (D));
@@ -4184,12 +4111,9 @@ package body GNAT.Altivec.Low_Level_Vectors is
begin
for N in Vchar_Range'Range loop
J := Natural (N) + M;
-
- if J <= Natural (Vchar_Range'Last) then
- D.Values (N) := VA.Values (Vchar_Range (J));
- else
- D.Values (N) := 0;
- end if;
+ D.Values (N) :=
+ (if J <= Natural (Vchar_Range'Last) then VA.Values (Vchar_Range (J))
+ else 0);
end loop;
return To_LL_VSI (To_Vector (D));
@@ -4530,12 +4454,8 @@ package body GNAT.Altivec.Low_Level_Vectors is
begin
for J in Vint_Range'Range loop
Subst_Result := SI64 (VA.Values (J)) - SI64 (VB.Values (J));
-
- if Subst_Result < SI64 (unsigned_int'First) then
- D.Values (J) := 0;
- else
- D.Values (J) := 1;
- end if;
+ D.Values (J) :=
+ (if Subst_Result < SI64 (unsigned_int'First) then 0 else 1);
end loop;
return To_LL_VSI (To_Vector (D));
@@ -5023,12 +4943,11 @@ package body GNAT.Altivec.Low_Level_Vectors is
D := To_View (vcmpbfp (B, C));
for J in Vint_Range'Range loop
+
-- vcmpbfp is not returning the usual bool vector; do the conversion
- if D.Values (J) = 0 then
- D.Values (J) := Signed_Bool_False;
- else
- D.Values (J) := Signed_Bool_True;
- end if;
+
+ D.Values (J) :=
+ (if D.Values (J) = 0 then Signed_Bool_False else Signed_Bool_True);
end loop;
return LL_VSI_Operations.Check_CR6 (A, D.Values);
diff --git a/gcc/ada/g-arrspl.adb b/gcc/ada/g-arrspl.adb
index 9a08b8282df..a897b13f913 100644
--- a/gcc/ada/g-arrspl.adb
+++ b/gcc/ada/g-arrspl.adb
@@ -238,10 +238,10 @@ package body GNAT.Array_Split is
loop
if K > Count_Sep then
- -- No more separators, last slice ends at the end of the source
- -- string.
+ -- No more separators, last slice ends at end of source string
Stop := S.Source'Last;
+
else
Stop := S.Indexes (K) - 1;
end if;
diff --git a/gcc/ada/g-comlin.adb b/gcc/ada/g-comlin.adb
index e655cad763d..eb982543b38 100644
--- a/gcc/ada/g-comlin.adb
+++ b/gcc/ada/g-comlin.adb
@@ -574,11 +574,8 @@ package body GNAT.Command_Line is
-- Depending on the value of Concatenate, the full switch is
-- a single character or the rest of the argument.
- if Concatenate then
- End_Index := Parser.Current_Index;
- else
- End_Index := Arg'Last;
- end if;
+ End_Index :=
+ (if Concatenate then Parser.Current_Index else Arg'Last);
if Switches (Switches'First) = '*' then
@@ -2279,20 +2276,16 @@ package body GNAT.Command_Line is
Cmd.Coalesce_Sections := new Argument_List (Cmd.Sections'Range);
for E in Cmd.Sections'Range loop
- if Cmd.Sections (E) = null then
- Cmd.Coalesce_Sections (E) := null;
- else
- Cmd.Coalesce_Sections (E) := new String'(Cmd.Sections (E).all);
- end if;
+ Cmd.Coalesce_Sections (E) :=
+ (if Cmd.Sections (E) = null then null
+ else new String'(Cmd.Sections (E).all));
end loop;
Cmd.Coalesce_Params := new Argument_List (Cmd.Params'Range);
for E in Cmd.Params'Range loop
- if Cmd.Params (E) = null then
- Cmd.Coalesce_Params (E) := null;
- else
- Cmd.Coalesce_Params (E) := new String'(Cmd.Params (E).all);
- end if;
+ Cmd.Coalesce_Params (E) :=
+ (if Cmd.Params (E) = null then null
+ else new String'(Cmd.Params (E).all));
end loop;
-- Not a clone, since we will not modify the parameters anyway
diff --git a/gcc/ada/g-comlin.ads b/gcc/ada/g-comlin.ads
index 5e8f63f420c..8752ddcff5f 100644
--- a/gcc/ada/g-comlin.ads
+++ b/gcc/ada/g-comlin.ads
@@ -622,8 +622,7 @@ package GNAT.Command_Line is
Section : String := "";
Add_Before : Boolean := False;
Success : out Boolean);
- -- Same as above, returning the status of
- -- the operation
+ -- Same as above, returning the status of the operation
procedure Remove_Switch
(Cmd : in out Command_Line;
diff --git a/gcc/ada/g-debpoo.adb b/gcc/ada/g-debpoo.adb
index 5127de9bdd4..ef7ce9e3dbd 100644
--- a/gcc/ada/g-debpoo.adb
+++ b/gcc/ada/g-debpoo.adb
@@ -985,11 +985,7 @@ package body GNAT.Debug_Pools is
is
begin
if H.Block_Size /= 0 then
- if In_Use then
- To_Byte (A).all := In_Use_Mark;
- else
- To_Byte (A).all := Free_Mark;
- end if;
+ To_Byte (A).all := (if In_Use then In_Use_Mark else Free_Mark);
end if;
end Mark;
@@ -1416,11 +1412,8 @@ package body GNAT.Debug_Pools is
Backtrace_Htable_Cumulate.Set (Elem);
if Cumulate then
- if Data.Kind = Alloc then
- K := Indirect_Alloc;
- else
- K := Indirect_Dealloc;
- end if;
+ K := (if Data.Kind = Alloc then Indirect_Alloc
+ else Indirect_Dealloc);
-- Propagate the direct call to all its parents
diff --git a/gcc/ada/g-dirope.adb b/gcc/ada/g-dirope.adb
index c7670ef558b..294aa7031ee 100644
--- a/gcc/ada/g-dirope.adb
+++ b/gcc/ada/g-dirope.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1998-2008, AdaCore --
+-- Copyright (C) 1998-2009, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -97,12 +97,7 @@ package body GNAT.Directory_Operations is
begin
-- Cut_Start point to the first basename character
- if Cut_Start = 0 then
- Cut_Start := Path'First;
-
- else
- Cut_Start := Cut_Start + 1;
- end if;
+ Cut_Start := (if Cut_Start = 0 then Path'First else Cut_Start + 1);
-- Cut_End point to the last basename character
@@ -580,11 +575,8 @@ package body GNAT.Directory_Operations is
begin
Local_Get_Current_Dir (Buffer'Address, Path_Len'Address);
- if Dir'Length > Path_Len then
- Last := Dir'First + Path_Len - 1;
- else
- Last := Dir'Last;
- end if;
+ Last :=
+ (if Dir'Length > Path_Len then Dir'First + Path_Len - 1 else Dir'Last);
Dir (Buffer'First .. Last) := Buffer (Buffer'First .. Last);
@@ -683,11 +675,9 @@ package body GNAT.Directory_Operations is
return;
end if;
- if Str'Length > Filename_Len then
- Last := Str'First + Filename_Len - 1;
- else
- Last := Str'Last;
- end if;
+ Last :=
+ (if Str'Length > Filename_Len then Str'First + Filename_Len - 1
+ else Str'Last);
declare
subtype Path_String is String (1 .. Filename_Len);
diff --git a/gcc/ada/g-dyntab.adb b/gcc/ada/g-dyntab.adb
index 1ebebe4d95d..2c3ae4fcd56 100644
--- a/gcc/ada/g-dyntab.adb
+++ b/gcc/ada/g-dyntab.adb
@@ -31,6 +31,8 @@
-- --
------------------------------------------------------------------------------
+pragma Compiler_Unit;
+
with GNAT.Heap_Sort_G;
with System; use System;
with System.Memory; use System.Memory;
@@ -64,10 +66,7 @@ package body GNAT.Dynamic_Tables is
-- Allocate --
--------------
- procedure Allocate
- (T : in out Instance;
- Num : Integer := 1)
- is
+ procedure Allocate (T : in out Instance; Num : Integer := 1) is
begin
T.P.Last_Val := T.P.Last_Val + Num;
diff --git a/gcc/ada/g-dyntab.ads b/gcc/ada/g-dyntab.ads
index 897d7008f82..89634554a7d 100644
--- a/gcc/ada/g-dyntab.ads
+++ b/gcc/ada/g-dyntab.ads
@@ -47,6 +47,8 @@
-- GNAT.Table and the GNAT compiler source unit Table to keep as much
-- coherency as possible between these three related units.
+pragma Compiler_Unit;
+
generic
type Table_Component_Type is private;
type Table_Index_Type is range <>;
diff --git a/gcc/ada/g-enblsp-vms-alpha.adb b/gcc/ada/g-enblsp-vms-alpha.adb
index 4b703263f59..64af051d825 100644
--- a/gcc/ada/g-enblsp-vms-alpha.adb
+++ b/gcc/ada/g-enblsp-vms-alpha.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2005-2008, AdaCore --
+-- Copyright (C) 2005-2009, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -77,11 +77,9 @@ begin
-- Fork a new process (it is not possible to do this in a subprogram)
- if Alloc_Vfork_Blocks >= 0 then
- Descriptor.Pid := Get_Current_Invo_Context (Get_Vfork_Jmpbuf);
- else
- Descriptor.Pid := -1;
- end if;
+ Descriptor.Pid :=
+ (if Alloc_Vfork_Blocks >= 0
+ then Get_Current_Invo_Context (Get_Vfork_Jmpbuf) else -1);
-- Are we now in the child
diff --git a/gcc/ada/g-enblsp-vms-ia64.adb b/gcc/ada/g-enblsp-vms-ia64.adb
index b7a9d340072..6ac7c5a0804 100644
--- a/gcc/ada/g-enblsp-vms-ia64.adb
+++ b/gcc/ada/g-enblsp-vms-ia64.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2005-2008, AdaCore --
+-- Copyright (C) 2005-2009, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -75,11 +75,8 @@ begin
-- Fork a new process (it is not possible to do this in a subprogram)
- if Alloc_Vfork_Blocks >= 0 then
- Descriptor.Pid := Setjmp1 (Get_Vfork_Jmpbuf);
- else
- Descriptor.Pid := -1;
- end if;
+ Descriptor.Pid :=
+ (if Alloc_Vfork_Blocks >= 0 then Setjmp1 (Get_Vfork_Jmpbuf) else -1);
-- Are we now in the child
diff --git a/gcc/ada/g-exctra.adb b/gcc/ada/g-exctra.adb
index 7d51ba4b79b..8534bbbb47e 100644
--- a/gcc/ada/g-exctra.adb
+++ b/gcc/ada/g-exctra.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2000-2005, AdaCore --
+-- Copyright (C) 2000-2009, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -88,17 +88,11 @@ package body GNAT.Exception_Traces is
procedure Set_Trace_Decorator (Decorator : Traceback_Decorator) is
begin
Current_Decorator := Decorator;
-
- if Current_Decorator /= null then
- Traceback_Decorator_Wrapper := Decorator_Wrapper'Access;
- else
- Traceback_Decorator_Wrapper := null;
- end if;
+ Traceback_Decorator_Wrapper :=
+ (if Current_Decorator /= null
+ then Decorator_Wrapper'Access else null);
end Set_Trace_Decorator;
- -- Trace_On/Trace_Off control the kind of automatic output to occur
- -- by way of the global Exception_Trace variable.
-
---------------
-- Trace_Off --
---------------
diff --git a/gcc/ada/g-expect-vms.adb b/gcc/ada/g-expect-vms.adb
index 429a66ca55c..cc413f7248d 100644
--- a/gcc/ada/g-expect-vms.adb
+++ b/gcc/ada/g-expect-vms.adb
@@ -1030,11 +1030,7 @@ package body GNAT.Expect is
Reinitialize_Buffer (Descriptor);
end if;
- if Add_LF then
- Last := Full_Str'Last;
- else
- Last := Full_Str'Last - 1;
- end if;
+ Last := (if Add_LF then Full_Str'Last else Full_Str'Last - 1);
Call_Filters (Descriptor, Full_Str (Full_Str'First .. Last), Input);
diff --git a/gcc/ada/g-expect.adb b/gcc/ada/g-expect.adb
index a67696a649d..6510c310813 100644
--- a/gcc/ada/g-expect.adb
+++ b/gcc/ada/g-expect.adb
@@ -1003,11 +1003,10 @@ package body GNAT.Expect is
-- Prepare low-level argument list from the normalized arguments
for K in Arg_List'Range loop
- if Arg_List (K) /= null then
- C_Arg_List (K) := Arg_List (K).all'Address;
- else
- C_Arg_List (K) := System.Null_Address;
- end if;
+ C_Arg_List (K) :=
+ (if Arg_List (K) /= null
+ then Arg_List (K).all'Address
+ else System.Null_Address);
end loop;
-- This does not return on Unix systems
diff --git a/gcc/ada/g-htable.adb b/gcc/ada/g-htable.adb
index 7cb2660fae2..aa6c6b7bcae 100644
--- a/gcc/ada/g-htable.adb
+++ b/gcc/ada/g-htable.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1995-2005, AdaCore --
+-- Copyright (C) 1995-2009, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -34,7 +34,9 @@
-- This is a dummy body, required because if we remove the body we have
-- bootstrap path problems (this unit used to have a body, and if we do not
-- supply a dummy body, the old incorrect body is picked up during the
--- bootstrap process.
+-- bootstrap process).
+
+pragma Compiler_Unit;
package body GNAT.HTable is
end GNAT.HTable;
diff --git a/gcc/ada/g-md5.adb b/gcc/ada/g-md5.adb
index 6c1148804fd..f8a462bc29c 100644
--- a/gcc/ada/g-md5.adb
+++ b/gcc/ada/g-md5.adb
@@ -4,9 +4,9 @@
-- --
-- G N A T . M D 5 --
-- --
--- B o d y --
+-- B o d y --
-- --
--- Copyright (C) 2002-2008, AdaCore --
+-- Copyright (C) 2009, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -16,8 +16,8 @@
-- 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 distributed with GNAT; see file COPYING. If not, write --
--- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
--- Boston, MA 02110-1301, USA. --
+-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
-- --
-- As a special exception, if other files instantiate generics from this --
-- unit, or you link this unit with other files to produce an executable, --
@@ -31,525 +31,8 @@
-- --
------------------------------------------------------------------------------
-with Ada.Unchecked_Conversion;
+-- This package does not require a body, since it is a package renaming. We
+-- provide a dummy file containing a No_Body pragma so that previous versions
+-- of the body (which did exist) will not interfere.
-package body GNAT.MD5 is
-
- use Interfaces;
-
- Padding : constant String :=
- (1 => Character'Val (16#80#), 2 .. 64 => ASCII.NUL);
-
- Hex_Digit : constant array (Unsigned_32 range 0 .. 15) of Character :=
- ('0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
- -- Look-up table for each hex digit of the Message-Digest.
- -- Used by function Digest (Context).
-
- -- The sixteen values used to rotate the context words.
- -- Four for each rounds. Used in procedure Transform.
-
- -- Round 1
-
- S11 : constant := 7;
- S12 : constant := 12;
- S13 : constant := 17;
- S14 : constant := 22;
-
- -- Round 2
-
- S21 : constant := 5;
- S22 : constant := 9;
- S23 : constant := 14;
- S24 : constant := 20;
-
- -- Round 3
-
- S31 : constant := 4;
- S32 : constant := 11;
- S33 : constant := 16;
- S34 : constant := 23;
-
- -- Round 4
-
- S41 : constant := 6;
- S42 : constant := 10;
- S43 : constant := 15;
- S44 : constant := 21;
-
- type Sixteen_Words is array (Natural range 0 .. 15)
- of Interfaces.Unsigned_32;
- -- Sixteen 32-bit words, converted from block of 64 characters.
- -- Used in procedure Decode and Transform.
-
- procedure Decode
- (Block : String;
- X : out Sixteen_Words);
- -- Convert a String of 64 characters into 16 32-bit numbers
-
- -- The following functions (F, FF, G, GG, H, HH, I and II) are the
- -- equivalent of the macros of the same name in the example
- -- C implementation in the annex of RFC 1321.
-
- function F (X, Y, Z : Unsigned_32) return Unsigned_32;
- pragma Inline (F);
-
- procedure FF
- (A : in out Unsigned_32;
- B, C, D : Unsigned_32;
- X : Unsigned_32;
- AC : Unsigned_32;
- S : Positive);
- pragma Inline (FF);
-
- function G (X, Y, Z : Unsigned_32) return Unsigned_32;
- pragma Inline (G);
-
- procedure GG
- (A : in out Unsigned_32;
- B, C, D : Unsigned_32;
- X : Unsigned_32;
- AC : Unsigned_32;
- S : Positive);
- pragma Inline (GG);
-
- function H (X, Y, Z : Unsigned_32) return Unsigned_32;
- pragma Inline (H);
-
- procedure HH
- (A : in out Unsigned_32;
- B, C, D : Unsigned_32;
- X : Unsigned_32;
- AC : Unsigned_32;
- S : Positive);
- pragma Inline (HH);
-
- function I (X, Y, Z : Unsigned_32) return Unsigned_32;
- pragma Inline (I);
-
- procedure II
- (A : in out Unsigned_32;
- B, C, D : Unsigned_32;
- X : Unsigned_32;
- AC : Unsigned_32;
- S : Positive);
- pragma Inline (II);
-
- procedure Transform
- (C : in out Context;
- Block : String);
- -- Process one block of 64 characters
-
- ------------
- -- Decode --
- ------------
-
- procedure Decode
- (Block : String;
- X : out Sixteen_Words)
- is
- Cur : Positive := Block'First;
-
- begin
- pragma Assert (Block'Length = 64);
-
- for Index in X'Range loop
- X (Index) :=
- Unsigned_32 (Character'Pos (Block (Cur))) +
- Shift_Left (Unsigned_32 (Character'Pos (Block (Cur + 1))), 8) +
- Shift_Left (Unsigned_32 (Character'Pos (Block (Cur + 2))), 16) +
- Shift_Left (Unsigned_32 (Character'Pos (Block (Cur + 3))), 24);
- Cur := Cur + 4;
- end loop;
- end Decode;
-
- ------------
- -- Digest --
- ------------
-
- function Digest (C : Context) return Message_Digest is
- Result : Message_Digest;
-
- Cur : Natural := 1;
- -- Index in Result where the next character will be placed
-
- Last_Block : String (1 .. 64);
-
- C1 : Context := C;
-
- procedure Convert (X : Unsigned_32);
- -- Put the contribution of one of the four words (A, B, C, D) of the
- -- Context in Result. Increments Cur.
-
- -------------
- -- Convert --
- -------------
-
- procedure Convert (X : Unsigned_32) is
- Y : Unsigned_32 := X;
- begin
- for J in 1 .. 4 loop
- Result (Cur + 1) := Hex_Digit (Y and Unsigned_32'(16#0F#));
- Y := Shift_Right (Y, 4);
- Result (Cur) := Hex_Digit (Y and Unsigned_32'(16#0F#));
- Y := Shift_Right (Y, 4);
- Cur := Cur + 2;
- end loop;
- end Convert;
-
- -- Start of processing for Digest
-
- begin
- -- Process characters in the context buffer, if any
-
- Last_Block (1 .. C.Last) := C.Buffer (1 .. C.Last);
-
- -- Too many magic literals below, should be defined as constants ???
-
- if C.Last > 55 then
- Last_Block (C.Last + 1 .. 64) := Padding (1 .. 64 - C.Last);
- Transform (C1, Last_Block);
- Last_Block := (others => ASCII.NUL);
-
- else
- Last_Block (C.Last + 1 .. 56) := Padding (1 .. 56 - C.Last);
- end if;
-
- -- Add the input length (as stored in the context) as 8 characters
-
- Last_Block (57 .. 64) := (others => ASCII.NUL);
-
- declare
- L : Unsigned_64 := Unsigned_64 (C.Length) * 8;
- Idx : Positive := 57;
-
- begin
- while L > 0 loop
- Last_Block (Idx) := Character'Val (L and 16#Ff#);
- L := Shift_Right (L, 8);
- Idx := Idx + 1;
- end loop;
- end;
-
- Transform (C1, Last_Block);
-
- Convert (C1.A);
- Convert (C1.B);
- Convert (C1.C);
- Convert (C1.D);
- return Result;
- end Digest;
-
- function Digest (S : String) return Message_Digest is
- C : Context;
- begin
- Update (C, S);
- return Digest (C);
- end Digest;
-
- function Digest
- (A : Ada.Streams.Stream_Element_Array) return Message_Digest
- is
- C : Context;
- begin
- Update (C, A);
- return Digest (C);
- end Digest;
-
- -------
- -- F --
- -------
-
- function F (X, Y, Z : Unsigned_32) return Unsigned_32 is
- begin
- return (X and Y) or ((not X) and Z);
- end F;
-
- --------
- -- FF --
- --------
-
- procedure FF
- (A : in out Unsigned_32;
- B, C, D : Unsigned_32;
- X : Unsigned_32;
- AC : Unsigned_32;
- S : Positive)
- is
- begin
- A := A + F (B, C, D) + X + AC;
- A := Rotate_Left (A, S);
- A := A + B;
- end FF;
-
- -------
- -- G --
- -------
-
- function G (X, Y, Z : Unsigned_32) return Unsigned_32 is
- begin
- return (X and Z) or (Y and (not Z));
- end G;
-
- --------
- -- GG --
- --------
-
- procedure GG
- (A : in out Unsigned_32;
- B, C, D : Unsigned_32;
- X : Unsigned_32;
- AC : Unsigned_32;
- S : Positive)
- is
- begin
- A := A + G (B, C, D) + X + AC;
- A := Rotate_Left (A, S);
- A := A + B;
- end GG;
-
- -------
- -- H --
- -------
-
- function H (X, Y, Z : Unsigned_32) return Unsigned_32 is
- begin
- return X xor Y xor Z;
- end H;
-
- --------
- -- HH --
- --------
-
- procedure HH
- (A : in out Unsigned_32;
- B, C, D : Unsigned_32;
- X : Unsigned_32;
- AC : Unsigned_32;
- S : Positive)
- is
- begin
- A := A + H (B, C, D) + X + AC;
- A := Rotate_Left (A, S);
- A := A + B;
- end HH;
-
- -------
- -- I --
- -------
-
- function I (X, Y, Z : Unsigned_32) return Unsigned_32 is
- begin
- return Y xor (X or (not Z));
- end I;
-
- --------
- -- II --
- --------
-
- procedure II
- (A : in out Unsigned_32;
- B, C, D : Unsigned_32;
- X : Unsigned_32;
- AC : Unsigned_32;
- S : Positive)
- is
- begin
- A := A + I (B, C, D) + X + AC;
- A := Rotate_Left (A, S);
- A := A + B;
- end II;
-
- ---------------
- -- Transform --
- ---------------
-
- procedure Transform
- (C : in out Context;
- Block : String)
- is
- X : Sixteen_Words;
-
- AA : Unsigned_32 := C.A;
- BB : Unsigned_32 := C.B;
- CC : Unsigned_32 := C.C;
- DD : Unsigned_32 := C.D;
-
- begin
- pragma Assert (Block'Length = 64);
-
- Decode (Block, X);
-
- -- Round 1
-
- FF (AA, BB, CC, DD, X (00), 16#D76aa478#, S11); -- 1
- FF (DD, AA, BB, CC, X (01), 16#E8c7b756#, S12); -- 2
- FF (CC, DD, AA, BB, X (02), 16#242070db#, S13); -- 3
- FF (BB, CC, DD, AA, X (03), 16#C1bdceee#, S14); -- 4
-
- FF (AA, BB, CC, DD, X (04), 16#f57c0faf#, S11); -- 5
- FF (DD, AA, BB, CC, X (05), 16#4787c62a#, S12); -- 6
- FF (CC, DD, AA, BB, X (06), 16#a8304613#, S13); -- 7
- FF (BB, CC, DD, AA, X (07), 16#fd469501#, S14); -- 8
-
- FF (AA, BB, CC, DD, X (08), 16#698098d8#, S11); -- 9
- FF (DD, AA, BB, CC, X (09), 16#8b44f7af#, S12); -- 10
- FF (CC, DD, AA, BB, X (10), 16#ffff5bb1#, S13); -- 11
- FF (BB, CC, DD, AA, X (11), 16#895cd7be#, S14); -- 12
-
- FF (AA, BB, CC, DD, X (12), 16#6b901122#, S11); -- 13
- FF (DD, AA, BB, CC, X (13), 16#fd987193#, S12); -- 14
- FF (CC, DD, AA, BB, X (14), 16#a679438e#, S13); -- 15
- FF (BB, CC, DD, AA, X (15), 16#49b40821#, S14); -- 16
-
- -- Round 2
-
- GG (AA, BB, CC, DD, X (01), 16#f61e2562#, S21); -- 17
- GG (DD, AA, BB, CC, X (06), 16#c040b340#, S22); -- 18
- GG (CC, DD, AA, BB, X (11), 16#265e5a51#, S23); -- 19
- GG (BB, CC, DD, AA, X (00), 16#e9b6c7aa#, S24); -- 20
-
- GG (AA, BB, CC, DD, X (05), 16#d62f105d#, S21); -- 21
- GG (DD, AA, BB, CC, X (10), 16#02441453#, S22); -- 22
- GG (CC, DD, AA, BB, X (15), 16#d8a1e681#, S23); -- 23
- GG (BB, CC, DD, AA, X (04), 16#e7d3fbc8#, S24); -- 24
-
- GG (AA, BB, CC, DD, X (09), 16#21e1cde6#, S21); -- 25
- GG (DD, AA, BB, CC, X (14), 16#c33707d6#, S22); -- 26
- GG (CC, DD, AA, BB, X (03), 16#f4d50d87#, S23); -- 27
- GG (BB, CC, DD, AA, X (08), 16#455a14ed#, S24); -- 28
-
- GG (AA, BB, CC, DD, X (13), 16#a9e3e905#, S21); -- 29
- GG (DD, AA, BB, CC, X (02), 16#fcefa3f8#, S22); -- 30
- GG (CC, DD, AA, BB, X (07), 16#676f02d9#, S23); -- 31
- GG (BB, CC, DD, AA, X (12), 16#8d2a4c8a#, S24); -- 32
-
- -- Round 3
-
- HH (AA, BB, CC, DD, X (05), 16#fffa3942#, S31); -- 33
- HH (DD, AA, BB, CC, X (08), 16#8771f681#, S32); -- 34
- HH (CC, DD, AA, BB, X (11), 16#6d9d6122#, S33); -- 35
- HH (BB, CC, DD, AA, X (14), 16#fde5380c#, S34); -- 36
-
- HH (AA, BB, CC, DD, X (01), 16#a4beea44#, S31); -- 37
- HH (DD, AA, BB, CC, X (04), 16#4bdecfa9#, S32); -- 38
- HH (CC, DD, AA, BB, X (07), 16#f6bb4b60#, S33); -- 39
- HH (BB, CC, DD, AA, X (10), 16#bebfbc70#, S34); -- 40
-
- HH (AA, BB, CC, DD, X (13), 16#289b7ec6#, S31); -- 41
- HH (DD, AA, BB, CC, X (00), 16#eaa127fa#, S32); -- 42
- HH (CC, DD, AA, BB, X (03), 16#d4ef3085#, S33); -- 43
- HH (BB, CC, DD, AA, X (06), 16#04881d05#, S34); -- 44
-
- HH (AA, BB, CC, DD, X (09), 16#d9d4d039#, S31); -- 45
- HH (DD, AA, BB, CC, X (12), 16#e6db99e5#, S32); -- 46
- HH (CC, DD, AA, BB, X (15), 16#1fa27cf8#, S33); -- 47
- HH (BB, CC, DD, AA, X (02), 16#c4ac5665#, S34); -- 48
-
- -- Round 4
-
- II (AA, BB, CC, DD, X (00), 16#f4292244#, S41); -- 49
- II (DD, AA, BB, CC, X (07), 16#432aff97#, S42); -- 50
- II (CC, DD, AA, BB, X (14), 16#ab9423a7#, S43); -- 51
- II (BB, CC, DD, AA, X (05), 16#fc93a039#, S44); -- 52
-
- II (AA, BB, CC, DD, X (12), 16#655b59c3#, S41); -- 53
- II (DD, AA, BB, CC, X (03), 16#8f0ccc92#, S42); -- 54
- II (CC, DD, AA, BB, X (10), 16#ffeff47d#, S43); -- 55
- II (BB, CC, DD, AA, X (01), 16#85845dd1#, S44); -- 56
-
- II (AA, BB, CC, DD, X (08), 16#6fa87e4f#, S41); -- 57
- II (DD, AA, BB, CC, X (15), 16#fe2ce6e0#, S42); -- 58
- II (CC, DD, AA, BB, X (06), 16#a3014314#, S43); -- 59
- II (BB, CC, DD, AA, X (13), 16#4e0811a1#, S44); -- 60
-
- II (AA, BB, CC, DD, X (04), 16#f7537e82#, S41); -- 61
- II (DD, AA, BB, CC, X (11), 16#bd3af235#, S42); -- 62
- II (CC, DD, AA, BB, X (02), 16#2ad7d2bb#, S43); -- 63
- II (BB, CC, DD, AA, X (09), 16#eb86d391#, S44); -- 64
-
- C.A := C.A + AA;
- C.B := C.B + BB;
- C.C := C.C + CC;
- C.D := C.D + DD;
-
- end Transform;
-
- ------------
- -- Update --
- ------------
-
- procedure Update
- (C : in out Context;
- Input : String)
- is
- Inp : constant String := C.Buffer (1 .. C.Last) & Input;
- Cur : Positive := Inp'First;
-
- begin
- C.Length := C.Length + Input'Length;
-
- while Cur + 63 <= Inp'Last loop
- Transform (C, Inp (Cur .. Cur + 63));
- Cur := Cur + 64;
- end loop;
-
- C.Last := Inp'Last - Cur + 1;
- C.Buffer (1 .. C.Last) := Inp (Cur .. Inp'Last);
- end Update;
-
- procedure Update
- (C : in out Context;
- Input : Ada.Streams.Stream_Element_Array)
- is
- subtype Stream_Array is Ada.Streams.Stream_Element_Array (Input'Range);
- subtype Stream_String is
- String (1 + Integer (Input'First) .. 1 + Integer (Input'Last));
-
- function To_String is new Ada.Unchecked_Conversion
- (Stream_Array, Stream_String);
-
- String_Input : constant String := To_String (Input);
- begin
- Update (C, String_Input);
- end Update;
-
- -----------------
- -- Wide_Digest --
- -----------------
-
- function Wide_Digest (W : Wide_String) return Message_Digest is
- C : Context;
- begin
- Wide_Update (C, W);
- return Digest (C);
- end Wide_Digest;
-
- -----------------
- -- Wide_Update --
- -----------------
-
- procedure Wide_Update
- (C : in out Context;
- Input : Wide_String)
- is
- String_Input : String (1 .. 2 * Input'Length);
- Cur : Positive := 1;
-
- begin
- for Index in Input'Range loop
- String_Input (Cur) :=
- Character'Val
- (Unsigned_32 (Wide_Character'Pos (Input (Index))) and 16#FF#);
- Cur := Cur + 1;
- String_Input (Cur) :=
- Character'Val
- (Shift_Right (Unsigned_32 (Wide_Character'Pos (Input (Index))), 8)
- and 16#FF#);
- Cur := Cur + 1;
- end loop;
-
- Update (C, String_Input);
- end Wide_Update;
-
-end GNAT.MD5;
+pragma No_Body;
diff --git a/gcc/ada/g-md5.ads b/gcc/ada/g-md5.ads
index cea8eb6a802..70eb007b32c 100644
--- a/gcc/ada/g-md5.ads
+++ b/gcc/ada/g-md5.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2002-2008, AdaCore --
+-- Copyright (C) 2009, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -16,8 +16,8 @@
-- 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 distributed with GNAT; see file COPYING. If not, write --
--- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
--- Boston, MA 02110-1301, USA. --
+-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
-- --
-- As a special exception, if other files instantiate generics from this --
-- unit, or you link this unit with other files to produce an executable, --
@@ -33,79 +33,19 @@
-- This package implements the MD5 Message-Digest Algorithm as described in
-- RFC 1321. The complete text of RFC 1321 can be found at:
---
-- http://www.ietf.org/rfc/rfc1321.txt
---
--- The implementation is derived from the RSA Data Security, Inc. MD5
--- Message-Digest Algorithm, as described in RFC 1321.
-with Ada.Streams;
-with Interfaces;
+-- See the declaration of GNAT.Secure_Hashes.H in g-sechas.ads for complete
+-- documentation.
-package GNAT.MD5 is
+with GNAT.Secure_Hashes.MD5;
+with System;
- type Context is private;
- -- This type is the four-word (16 byte) MD buffer, as described in
- -- RFC 1321 (3.3). Its initial value is Initial_Context below.
-
- Initial_Context : constant Context;
- -- Initial value of a Context object. May be used to reinitialize
- -- a Context value by simple assignment of this value to the object.
-
- procedure Update
- (C : in out Context;
- Input : String);
- procedure Wide_Update
- (C : in out Context;
- Input : Wide_String);
- procedure Update
- (C : in out Context;
- Input : Ada.Streams.Stream_Element_Array);
- -- Modify the Context C. If C has the initial value Initial_Context,
- -- then, after a call to one of these procedures, Digest (C) will return
- -- the Message-Digest of Input.
- --
- -- These procedures may be called successively with the same context and
- -- different inputs, and these several successive calls will produce
- -- the same final context as a call with the concatenation of the inputs.
-
- subtype Message_Digest is String (1 .. 32);
- -- The string type returned by function Digest
-
- function Digest (C : Context) return Message_Digest;
- -- Extracts the Message-Digest from a context. This function should be
- -- used after one or several calls to Update.
-
- function Digest (S : String) return Message_Digest;
- function Wide_Digest (W : Wide_String) return Message_Digest;
- function Digest
- (A : Ada.Streams.Stream_Element_Array)
- return Message_Digest;
- -- These functions are equivalent to the corresponding Update (or
- -- Wide_Update) on a default initialized Context, followed by Digest
- -- on the resulting Context.
-
-private
-
- -- Magic numbers
-
- Initial_A : constant := 16#67452301#;
- Initial_B : constant := 16#EFCDAB89#;
- Initial_C : constant := 16#98BADCFE#;
- Initial_D : constant := 16#10325476#;
-
- type Context is record
- A : Interfaces.Unsigned_32 := Initial_A;
- B : Interfaces.Unsigned_32 := Initial_B;
- C : Interfaces.Unsigned_32 := Initial_C;
- D : Interfaces.Unsigned_32 := Initial_D;
- Buffer : String (1 .. 64) := (others => ASCII.NUL);
- Last : Natural := 0;
- Length : Natural := 0;
- end record;
-
- Initial_Context : constant Context :=
- (A => Initial_A, B => Initial_B, C => Initial_C, D => Initial_D,
- Buffer => (others => ASCII.NUL), Last => 0, Length => 0);
-
-end GNAT.MD5;
+package GNAT.MD5 is new GNAT.Secure_Hashes.H
+ (Block_Words => GNAT.Secure_Hashes.MD5.Block_Words,
+ State_Words => 4,
+ Hash_Words => 4,
+ Hash_Bit_Order => System.Low_Order_First,
+ Hash_State => GNAT.Secure_Hashes.MD5.Hash_State,
+ Initial_State => GNAT.Secure_Hashes.MD5.Initial_State,
+ Transform => GNAT.Secure_Hashes.MD5.Transform);
diff --git a/gcc/ada/g-pehage.adb b/gcc/ada/g-pehage.adb
index 5abb04c2138..e96b9cc0c58 100644
--- a/gcc/ada/g-pehage.adb
+++ b/gcc/ada/g-pehage.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002-2008, AdaCore --
+-- Copyright (C) 2002-2009, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -1970,11 +1970,7 @@ package body GNAT.Perfect_Hash_Generators is
Q := Seed / 127773;
X := 16807 * R - 2836 * Q;
- if X < 0 then
- Seed := X + 2147483647;
- else
- Seed := X;
- end if;
+ Seed := (if X < 0 then X + 2147483647 else X);
end Random;
-------------
@@ -2233,11 +2229,8 @@ package body GNAT.Perfect_Hash_Generators is
-- The first position should not exceed the minimum key length.
-- Otherwise, we may end up with an empty word once reduced.
- if Last_Sel_Pos = 0 then
- Max_Sel_Pos := Min_Key_Len;
- else
- Max_Sel_Pos := Max_Key_Len;
- end if;
+ Max_Sel_Pos :=
+ (if Last_Sel_Pos = 0 then Min_Key_Len else Max_Key_Len);
-- Find which position increases more the number of differences
diff --git a/gcc/ada/g-regist.adb b/gcc/ada/g-regist.adb
index 2c706ff69e4..c04248e588f 100644
--- a/gcc/ada/g-regist.adb
+++ b/gcc/ada/g-regist.adb
@@ -417,11 +417,7 @@ package body GNAT.Registry is
Result : LONG;
begin
- if Expand then
- Value_Type := REG_EXPAND_SZ;
- else
- Value_Type := REG_SZ;
- end if;
+ Value_Type := (if Expand then REG_EXPAND_SZ else REG_SZ);
Result :=
RegSetValueEx
diff --git a/gcc/ada/g-sercom-linux.adb b/gcc/ada/g-sercom-linux.adb
index 1be595a2f63..a89b09b8d08 100644
--- a/gcc/ada/g-sercom-linux.adb
+++ b/gcc/ada/g-sercom-linux.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2007-2008, AdaCore --
+-- Copyright (C) 2007-2009, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -37,7 +37,9 @@ with Ada.Streams; use Ada.Streams;
with Ada; use Ada;
with Ada.Unchecked_Deallocation;
-with System.CRTL; use System, System.CRTL;
+with System; use System;
+with System.Communication; use System.Communication;
+with System.CRTL; use System.CRTL;
with GNAT.OS_Lib; use GNAT.OS_Lib;
@@ -167,11 +169,10 @@ package body GNAT.Serial_Communications is
Res := read (Integer (Port.H.all), Buffer'Address, Len);
if Res = -1 then
- Last := 0;
Raise_Error ("read failed");
- else
- Last := Buffer'First + Stream_Element_Offset (Res) - 1;
end if;
+
+ Last := Last_Index (Buffer'First, size_t (Res));
end Read;
---------
@@ -210,7 +211,10 @@ package body GNAT.Serial_Communications is
pragma Import (C, tcflush, "tcflush");
Current : termios;
- Res : int;
+
+ Res : int;
+ pragma Warnings (Off, Res);
+ -- Warnings off, since we don't always test the result
begin
if Port.H = null then
@@ -245,11 +249,7 @@ package body GNAT.Serial_Communications is
-- Block
- if Block then
- Res := fcntl (int (Port.H.all), F_SETFL, 0);
- else
- Res := fcntl (int (Port.H.all), F_SETFL, FNDELAY);
- end if;
+ Res := fcntl (int (Port.H.all), F_SETFL, (if Block then 0 else FNDELAY));
if Res = -1 then
Raise_Error ("set: fcntl failed");
diff --git a/gcc/ada/g-sercom-mingw.adb b/gcc/ada/g-sercom-mingw.adb
index 03bd6aba191..cc6123bbc7c 100644
--- a/gcc/ada/g-sercom-mingw.adb
+++ b/gcc/ada/g-sercom-mingw.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2007-2008, AdaCore --
+-- Copyright (C) 2007-2009, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -35,7 +35,12 @@
with Ada.Unchecked_Deallocation; use Ada;
with Ada.Streams; use Ada.Streams;
-with System.Win32.Ext; use System, System.Win32, System.Win32.Ext;
+
+with System; use System;
+with System.Communication; use System.Communication;
+with System.CRTL; use System.CRTL;
+with System.Win32; use System.Win32;
+with System.Win32.Ext; use System.Win32.Ext;
package body GNAT.Serial_Communications is
@@ -158,7 +163,7 @@ package body GNAT.Serial_Communications is
Raise_Error ("read error");
end if;
- Last := Buffer'First - 1 + Stream_Element_Offset (Read_Last);
+ Last := Last_Index (Buffer'First, size_t (Read_Last));
end Read;
---------
diff --git a/gcc/ada/g-sercom.ads b/gcc/ada/g-sercom.ads
index 8b4c5590684..a3c4b0c610b 100644
--- a/gcc/ada/g-sercom.ads
+++ b/gcc/ada/g-sercom.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2007-2008, AdaCore --
+-- Copyright (C) 2007-2009, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -91,7 +91,9 @@ package GNAT.Serial_Communications is
Buffer : out Ada.Streams.Stream_Element_Array;
Last : out Ada.Streams.Stream_Element_Offset);
-- Read a set of bytes, put result into Buffer and set Last accordingly.
- -- Last is set to 0 if no byte has been read.
+ -- Last is set to Buffer'First - 1 if no byte has been read, unless
+ -- Buffer'First = Stream_Element_Offset'First, in which case
+ -- Constraint_Error raised instead.
overriding procedure Write
(Port : in out Serial_Port;
diff --git a/gcc/ada/g-sha1.adb b/gcc/ada/g-sha1.adb
index 72b19244a36..edc6b43d9c0 100644
--- a/gcc/ada/g-sha1.adb
+++ b/gcc/ada/g-sha1.adb
@@ -4,376 +4,33 @@
-- --
-- G N A T . S H A 1 --
-- --
--- B o d y --
+-- B o d y --
-- --
--- Copyright (C) 2002-2006, AdaCore --
+-- Copyright (C) 2009, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
--- ware Foundation; either version 2, or (at your option) any later ver- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT 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 distributed with GNAT; see file COPYING. If not, write --
--- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
--- Boston, MA 02110-1301, USA. --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
-- --
--- As a special exception, if other files instantiate generics from this --
--- unit, or you link this unit with other files to produce an executable, --
--- this unit does not by itself cause the resulting executable to be --
--- covered by the GNU General Public License. This exception does not --
--- however invalidate any other reasons why the executable file might be --
--- covered by the GNU Public License. --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
--- Note: the code for this unit is derived from GNAT.MD5
-
-with Ada.Unchecked_Conversion;
-
-package body GNAT.SHA1 is
-
- use Interfaces;
-
- Padding : constant String :=
- (1 => Character'Val (16#80#), 2 .. 64 => ASCII.NUL);
-
- Hex_Digit : constant array (Unsigned_32 range 0 .. 15) of Character :=
- ('0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
- -- Look-up table for each hex digit of the Message-Digest.
- -- Used by function Digest (Context).
-
- type Sixteen_Words is array (Natural range 0 .. 15)
- of Interfaces.Unsigned_32;
- -- Sixteen 32-bit words, converted from block of 64 characters.
- -- Used in procedure Decode and Transform.
-
- procedure Decode (Block : String; X : out Sixteen_Words);
- -- Convert a String of 64 characters into 16 32-bit numbers
-
- -- The following functions are the four elementary components of each
- -- of the four round groups (0 .. 19, 20 .. 39, 40 .. 59, and 60 .. 79)
- -- defined in RFC 3174.
-
- function F0 (B, C, D : Unsigned_32) return Unsigned_32;
- pragma Inline (F0);
-
- function F1 (B, C, D : Unsigned_32) return Unsigned_32;
- pragma Inline (F1);
-
- function F2 (B, C, D : Unsigned_32) return Unsigned_32;
- pragma Inline (F2);
-
- function F3 (B, C, D : Unsigned_32) return Unsigned_32;
- pragma Inline (F3);
-
- procedure Transform (Ctx : in out Context; Block : String);
- -- Process one block of 64 characters
-
- ------------
- -- Decode --
- ------------
-
- procedure Decode (Block : String; X : out Sixteen_Words) is
- Cur : Positive := Block'First;
-
- begin
- pragma Assert (Block'Length = 64);
-
- for Index in X'Range loop
- X (Index) :=
- Unsigned_32 (Character'Pos (Block (Cur + 3))) +
- Shift_Left (Unsigned_32 (Character'Pos (Block (Cur + 2))), 8) +
- Shift_Left (Unsigned_32 (Character'Pos (Block (Cur + 1))), 16) +
- Shift_Left (Unsigned_32 (Character'Pos (Block (Cur))), 24);
- Cur := Cur + 4;
- end loop;
- end Decode;
-
- ------------
- -- Digest --
- ------------
-
- function Digest (C : Context) return Message_Digest is
- Result : Message_Digest;
-
- Cur : Natural := 1;
- -- Index in Result where the next character will be placed
-
- Last_Block : String (1 .. 64);
-
- C1 : Context := C;
-
- procedure Convert (X : Unsigned_32);
- -- Put the contribution of one of the five H words of the Context in
- -- Result. Increments Cur.
-
- -------------
- -- Convert --
- -------------
-
- procedure Convert (X : Unsigned_32) is
- Y : Unsigned_32 := X;
- begin
- for J in 1 .. 8 loop
- Y := Rotate_Left (Y, 4);
- Result (Cur) := Hex_Digit (Y and Unsigned_32'(16#0F#));
- Cur := Cur + 1;
- end loop;
- end Convert;
-
- -- Start of processing for Digest
-
- begin
- -- Process characters in the context buffer, if any
-
- pragma Assert (C.Last /= C.Buffer'Last);
- Last_Block (1 .. C.Last) := C.Buffer (1 .. C.Last);
-
- if C.Last > 55 then
- Last_Block (C.Last + 1 .. 64) := Padding (1 .. 64 - C.Last);
- Transform (C1, Last_Block);
- Last_Block := (others => ASCII.NUL);
-
- else
- Last_Block (C.Last + 1 .. 56) := Padding (1 .. 56 - C.Last);
- end if;
-
- -- Add the input length (as stored in the context) as 8 characters
-
- Last_Block (57 .. 64) := (others => ASCII.NUL);
-
- declare
- L : Unsigned_64 := Unsigned_64 (C.Length) * 8;
- Idx : Positive := 64;
- begin
- while L > 0 loop
- Last_Block (Idx) := Character'Val (L and 16#Ff#);
- L := Shift_Right (L, 8);
- Idx := Idx - 1;
- end loop;
- end;
-
- Transform (C1, Last_Block);
-
- Convert (C1.H (0));
- Convert (C1.H (1));
- Convert (C1.H (2));
- Convert (C1.H (3));
- Convert (C1.H (4));
- return Result;
- end Digest;
-
- function Digest (S : String) return Message_Digest is
- C : Context;
- begin
- Update (C, S);
- return Digest (C);
- end Digest;
-
- function Digest
- (A : Ada.Streams.Stream_Element_Array) return Message_Digest
- is
- C : Context;
- begin
- Update (C, A);
- return Digest (C);
- end Digest;
-
- --------
- -- F0 --
- --------
-
- function F0
- (B, C, D : Interfaces.Unsigned_32) return Interfaces.Unsigned_32
- is
- begin
- return (B and C) or ((not B) and D);
- end F0;
-
- --------
- -- F1 --
- --------
-
- function F1
- (B, C, D : Interfaces.Unsigned_32) return Interfaces.Unsigned_32
- is
- begin
- return B xor C xor D;
- end F1;
-
- --------
- -- F2 --
- --------
-
- function F2
- (B, C, D : Interfaces.Unsigned_32) return Interfaces.Unsigned_32
- is
- begin
- return (B and C) or (B and D) or (C and D);
- end F2;
-
- --------
- -- F3 --
- --------
-
- function F3
- (B, C, D : Interfaces.Unsigned_32) return Interfaces.Unsigned_32
- renames F1;
-
- ---------------
- -- Transform --
- ---------------
-
- procedure Transform
- (Ctx : in out Context;
- Block : String)
- is
- W : array (0 .. 79) of Interfaces.Unsigned_32;
-
- A, B, C, D, E, Temp : Interfaces.Unsigned_32;
-
- begin
- pragma Assert (Block'Length = 64);
-
- -- a. Divide data block into sixteen words
-
- Decode (Block, Sixteen_Words (W (0 .. 15)));
-
- -- b. Prepare working block of 80 words
-
- for T in 16 .. 79 loop
-
- -- W(t) = S^1(W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16))
-
- W (T) := Rotate_Left
- (W (T - 3) xor W (T - 8) xor W (T - 14) xor W (T - 16), 1);
-
- end loop;
-
- -- c. Set up transformation variables
-
- A := Ctx.H (0);
- B := Ctx.H (1);
- C := Ctx.H (2);
- D := Ctx.H (3);
- E := Ctx.H (4);
-
- -- d. For each of the 80 rounds, compute:
-
- -- TEMP = S^5(A) + f(t;B,C,D) + E + W(t) + K(t);
- -- E = D; D = C; C = S^30(B); B = A; A = TEMP;
-
- for T in 0 .. 19 loop
- Temp := Rotate_Left (A, 5) + F0 (B, C, D) + E + W (T) + 16#5A827999#;
- E := D; D := C; C := Rotate_Left (B, 30); B := A; A := Temp;
- end loop;
-
- for T in 20 .. 39 loop
- Temp := Rotate_Left (A, 5) + F1 (B, C, D) + E + W (T) + 16#6ED9EBA1#;
- E := D; D := C; C := Rotate_Left (B, 30); B := A; A := Temp;
- end loop;
-
- for T in 40 .. 59 loop
- Temp := Rotate_Left (A, 5) + F2 (B, C, D) + E + W (T) + 16#8F1BBCDC#;
- E := D; D := C; C := Rotate_Left (B, 30); B := A; A := Temp;
- end loop;
-
- for T in 60 .. 79 loop
- Temp := Rotate_Left (A, 5) + F3 (B, C, D) + E + W (T) + 16#CA62C1D6#;
- E := D; D := C; C := Rotate_Left (B, 30); B := A; A := Temp;
- end loop;
-
- -- e. Update context:
- -- H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4 + E
-
- Ctx.H (0) := Ctx.H (0) + A;
- Ctx.H (1) := Ctx.H (1) + B;
- Ctx.H (2) := Ctx.H (2) + C;
- Ctx.H (3) := Ctx.H (3) + D;
- Ctx.H (4) := Ctx.H (4) + E;
- end Transform;
-
- ------------
- -- Update --
- ------------
-
- procedure Update
- (C : in out Context;
- Input : String)
- is
- Inp : constant String := C.Buffer (1 .. C.Last) & Input;
- Cur : Positive := Inp'First;
-
- begin
- C.Length := C.Length + Input'Length;
-
- while Cur + 63 <= Inp'Last loop
- Transform (C, Inp (Cur .. Cur + 63));
- Cur := Cur + 64;
- end loop;
-
- C.Last := Inp'Last - Cur + 1;
- C.Buffer (1 .. C.Last) := Inp (Cur .. Inp'Last);
- end Update;
-
- procedure Update
- (C : in out Context;
- Input : Ada.Streams.Stream_Element_Array)
- is
- subtype Stream_Array is Ada.Streams.Stream_Element_Array (Input'Range);
- subtype Stream_String is
- String (1 + Integer (Input'First) .. 1 + Integer (Input'Last));
-
- function To_String is new Ada.Unchecked_Conversion
- (Stream_Array, Stream_String);
-
- String_Input : constant String := To_String (Input);
- begin
- Update (C, String_Input);
- end Update;
-
- -----------------
- -- Wide_Digest --
- -----------------
-
- function Wide_Digest (W : Wide_String) return Message_Digest is
- C : Context;
- begin
- Wide_Update (C, W);
- return Digest (C);
- end Wide_Digest;
-
- -----------------
- -- Wide_Update --
- -----------------
-
- procedure Wide_Update
- (C : in out Context;
- Input : Wide_String)
- is
- String_Input : String (1 .. 2 * Input'Length);
- Cur : Positive := 1;
-
- begin
- for Index in Input'Range loop
- String_Input (Cur) :=
- Character'Val
- (Unsigned_32 (Wide_Character'Pos (Input (Index))) and 16#FF#);
- Cur := Cur + 1;
- String_Input (Cur) :=
- Character'Val
- (Shift_Right (Unsigned_32 (Wide_Character'Pos (Input (Index))), 8)
- and 16#FF#);
- Cur := Cur + 1;
- end loop;
-
- Update (C, String_Input);
- end Wide_Update;
+-- This package does not require a body, since it is a package renaming. We
+-- provide a dummy file containing a No_Body pragma so that previous versions
+-- of the body (which did exist) will not interfere.
-end GNAT.SHA1;
+pragma No_Body;
diff --git a/gcc/ada/g-sha1.ads b/gcc/ada/g-sha1.ads
index 36e2e25d853..39132054ddf 100644
--- a/gcc/ada/g-sha1.ads
+++ b/gcc/ada/g-sha1.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2002-2006, AdaCore --
+-- Copyright (C) 2009, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -16,8 +16,8 @@
-- 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 distributed with GNAT; see file COPYING. If not, write --
--- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
--- Boston, MA 02110-1301, USA. --
+-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
-- --
-- As a special exception, if other files instantiate generics from this --
-- unit, or you link this unit with other files to produce an executable, --
@@ -31,86 +31,21 @@
-- --
------------------------------------------------------------------------------
--- This package implements the US Secure Hash Algorithm 1 (SHA1) as described
--- in RFC 3174. The complete text of RFC 3174 can be found at:
+-- This package implaments the SHA-1 secure hash function as decsribed in
+-- FIPS PUB 180-3. The complete text of FIPS PUB 180-3 can be found at:
+-- http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf
--- http://www.ietf.org/rfc/rfc3174.txt
+-- See the declaration of GNAT.Secure_Hashes.H in g-sechas.ads for complete
+-- documentation.
--- Note: the code for this unit is derived from GNAT.MD5
+with GNAT.Secure_Hashes.SHA1;
+with System;
-with Ada.Streams;
-with Interfaces;
-
-package GNAT.SHA1 is
-
- type Context is private;
- -- This type holds the five-word (20 byte) buffer H, as described in
- -- RFC 3174 (6.1). Its initial value is Initial_Context below.
-
- Initial_Context : constant Context;
- -- Initial value of a Context object. May be used to reinitialize
- -- a Context value by simple assignment of this value to the object.
-
- procedure Update
- (C : in out Context;
- Input : String);
- procedure Wide_Update
- (C : in out Context;
- Input : Wide_String);
- procedure Update
- (C : in out Context;
- Input : Ada.Streams.Stream_Element_Array);
- -- Modify the Context C. If C has the initial value Initial_Context,
- -- then, after a call to one of these procedures, Digest (C) will return
- -- the Message-Digest of Input.
- --
- -- These procedures may be called successively with the same context and
- -- different inputs, and these several successive calls will produce
- -- the same final context as a call with the concatenation of the inputs.
-
- subtype Message_Digest is String (1 .. 40);
- -- The string type returned by function Digest
-
- function Digest (C : Context) return Message_Digest;
- -- Extracts the Message-Digest from a context. This function should be
- -- used after one or several calls to Update.
-
- function Digest (S : String) return Message_Digest;
- function Wide_Digest (W : Wide_String) return Message_Digest;
- function Digest
- (A : Ada.Streams.Stream_Element_Array) return Message_Digest;
- -- These functions are equivalent to the corresponding Update (or
- -- Wide_Update) on a default initialized Context, followed by Digest
- -- on the resulting Context.
-
-private
-
- -- Magic numbers
-
- Initial_H0 : constant := 16#67452301#;
- Initial_H1 : constant := 16#EFCDAB89#;
- Initial_H2 : constant := 16#98BADCFE#;
- Initial_H3 : constant := 16#10325476#;
- Initial_H4 : constant := 16#C3D2E1F0#;
-
- type H_Type is array (0 .. 4) of Interfaces.Unsigned_32;
-
- Initial_H : constant H_Type :=
- (0 => Initial_H0,
- 1 => Initial_H1,
- 2 => Initial_H2,
- 3 => Initial_H3,
- 4 => Initial_H4);
-
- type Context is record
- H : H_Type := Initial_H;
- Buffer : String (1 .. 64) := (others => ASCII.NUL);
- Last : Natural := 0;
- Length : Natural := 0;
- end record;
-
- Initial_Context : constant Context :=
- (H => Initial_H,
- Buffer => (others => ASCII.NUL), Last => 0, Length => 0);
-
-end GNAT.SHA1;
+package GNAT.SHA1 is new GNAT.Secure_Hashes.H
+ (Block_Words => GNAT.Secure_Hashes.SHA1.Block_Words,
+ State_Words => 5,
+ Hash_Words => 5,
+ Hash_Bit_Order => System.High_Order_First,
+ Hash_State => GNAT.Secure_Hashes.SHA1.Hash_State,
+ Initial_State => GNAT.Secure_Hashes.SHA1.Initial_State,
+ Transform => GNAT.Secure_Hashes.SHA1.Transform);
diff --git a/gcc/ada/g-socket.adb b/gcc/ada/g-socket.adb
index 7741dc0c76d..09537baf452 100644
--- a/gcc/ada/g-socket.adb
+++ b/gcc/ada/g-socket.adb
@@ -46,7 +46,9 @@ with GNAT.Sockets.Linker_Options;
pragma Warnings (Off, GNAT.Sockets.Linker_Options);
-- Need to include pragma Linker_Options which is platform dependent
-with System; use System;
+with System; use System;
+with System.Communication; use System.Communication;
+with System.CRTL; use System.CRTL;
package body GNAT.Sockets is
@@ -162,7 +164,7 @@ package body GNAT.Sockets is
function To_Host_Entry (E : Hostent) return Host_Entry_Type;
-- Conversion function
- function To_Service_Entry (E : Servent) return Service_Entry_Type;
+ function To_Service_Entry (E : Servent_Access) return Service_Entry_Type;
-- Conversion function
function To_Timeval (Val : Timeval_Duration) return Timeval;
@@ -249,14 +251,6 @@ package body GNAT.Sockets is
function Err_Code_Image (E : Integer) return String;
-- Return the value of E surrounded with brackets
- function Last_Index
- (First : Stream_Element_Offset;
- Count : C.int) return Stream_Element_Offset;
- -- Compute the Last OUT parameter for the various Receive_Socket
- -- subprograms: returns First + Count - 1, except for the case
- -- where First = Stream_Element_Offset'First and Res = 0, in which
- -- case Stream_Element_Offset'Last is returned instead.
-
procedure Initialize (X : in out Sockets_Library_Controller);
procedure Finalize (X : in out Sockets_Library_Controller);
@@ -977,7 +971,7 @@ package body GNAT.Sockets is
-- Translate from the C format to the API format
- return To_Service_Entry (Res);
+ return To_Service_Entry (Res'Unchecked_Access);
end Get_Service_By_Name;
-------------------------
@@ -1003,7 +997,7 @@ package body GNAT.Sockets is
-- Translate from the C format to the API format
- return To_Service_Entry (Res);
+ return To_Service_Entry (Res'Unchecked_Access);
end Get_Service_By_Port;
---------------------
@@ -1416,22 +1410,6 @@ package body GNAT.Sockets is
and then Is_Socket_In_Set (Item.Set'Access, C.int (Socket)) /= 0;
end Is_Set;
- ----------------
- -- Last_Index --
- ----------------
-
- function Last_Index
- (First : Stream_Element_Offset;
- Count : C.int) return Stream_Element_Offset
- is
- begin
- if First = Stream_Element_Offset'First and then Count = 0 then
- return Stream_Element_Offset'Last;
- else
- return First + Stream_Element_Offset (Count - 1);
- end if;
- end Last_Index;
-
-------------------
-- Listen_Socket --
-------------------
@@ -1659,7 +1637,7 @@ package body GNAT.Sockets is
Raise_Socket_Error (Socket_Errno);
end if;
- Last := Last_Index (First => Item'First, Count => Res);
+ Last := Last_Index (First => Item'First, Count => size_t (Res));
end Receive_Socket;
--------------------
@@ -1691,7 +1669,7 @@ package body GNAT.Sockets is
Raise_Socket_Error (Socket_Errno);
end if;
- Last := Last_Index (First => Item'First, Count => Res);
+ Last := Last_Index (First => Item'First, Count => size_t (Res));
To_Inet_Addr (Sin.Sin_Addr, From.Addr);
From.Port := Port_Type (Network_To_Short (Sin.Sin_Port));
@@ -1940,7 +1918,7 @@ package body GNAT.Sockets is
Raise_Socket_Error (Socket_Errno);
end if;
- Last := Last_Index (First => Item'First, Count => Res);
+ Last := Last_Index (First => Item'First, Count => size_t (Res));
end Send_Socket;
-----------------
@@ -2375,17 +2353,17 @@ package body GNAT.Sockets is
-- To_Service_Entry --
----------------------
- function To_Service_Entry (E : Servent) return Service_Entry_Type is
+ function To_Service_Entry (E : Servent_Access) return Service_Entry_Type is
use type C.size_t;
- Official : constant String := C.Strings.Value (E.S_Name);
+ Official : constant String := C.Strings.Value (Servent_S_Name (E));
Aliases : constant Chars_Ptr_Array :=
- Chars_Ptr_Pointers.Value (E.S_Aliases);
+ Chars_Ptr_Pointers.Value (Servent_S_Aliases (E));
-- S_Aliases points to a list of name aliases. The list is
-- terminated by a NULL pointer.
- Protocol : constant String := C.Strings.Value (E.S_Proto);
+ Protocol : constant String := C.Strings.Value (Servent_S_Proto (E));
Result : Service_Entry_Type (Aliases_Length => Aliases'Length - 1);
-- The last element is a null pointer
@@ -2406,7 +2384,7 @@ package body GNAT.Sockets is
end loop;
Result.Port :=
- Port_Type (Network_To_Short (C.unsigned_short (E.S_Port)));
+ Port_Type (Network_To_Short (C.unsigned_short (Servent_S_Port (E))));
Result.Protocol := To_Name (Protocol);
return Result;
diff --git a/gcc/ada/g-socket.ads b/gcc/ada/g-socket.ads
index 39a917a5480..8d3138e65d6 100644
--- a/gcc/ada/g-socket.ads
+++ b/gcc/ada/g-socket.ads
@@ -895,10 +895,11 @@ package GNAT.Sockets is
Flags : Request_Flag_Type := No_Request_Flag);
-- Receive message from Socket. Last is the index value such that Item
-- (Last) is the last character assigned. Note that Last is set to
- -- Item'First - 1 (or to Stream_Element_Array'Last if Item'First is
- -- Stream_Element_Offset'First) when the socket has been closed by peer.
- -- This is not an error and no exception is raised. Flags allows to
- -- control the reception. Raise Socket_Error on error.
+ -- Item'First - 1 when the socket has been closed by peer. This is not
+ -- an error, and no exception is raised in this case unless Item'First
+ -- is Stream_Element_Offset'First, in which case Constraint_Error is
+ -- raised. Flags allows to control the reception. Raise Socket_Error on
+ -- error.
procedure Receive_Socket
(Socket : Socket_Type;
@@ -937,12 +938,13 @@ package GNAT.Sockets is
-- Transmit a message over a socket. For a datagram socket, the address
-- is given by To.all. For a stream socket, To must be null. Last
-- is the index value such that Item (Last) is the last character
- -- sent. Note that Last is set to Item'First - 1 (if Item'First is
- -- Stream_Element_Offset'First, to Stream_Element_Array'Last) when the
- -- socket has been closed by peer. This is not an error and no exception
- -- is raised. Flags allows control of the transmission. Raises exception
- -- Socket_Error on error. Note: this subprogram is inlined because it is
- -- also used to implement the two variants below.
+ -- sent. Note that Last is set to Item'First - 1 if the socket has been
+ -- closed by the peer (unless Item'First is Stream_Element_Offset'First,
+ -- in which case Constraint_Error is raised instead). This is not an error,
+ -- and Socket_Error is not raised in that case. Flags allows control of the
+ -- transmission. Raises exception Socket_Error on error. Note: this
+ -- subprogram is inlined because it is also used to implement the two
+ -- variants below.
procedure Send_Socket
(Socket : Socket_Type;
diff --git a/gcc/ada/g-socthi-mingw.ads b/gcc/ada/g-socthi-mingw.ads
index 8ec056148f1..6d851e17cb4 100644
--- a/gcc/ada/g-socthi-mingw.ads
+++ b/gcc/ada/g-socthi-mingw.ads
@@ -184,9 +184,6 @@ package GNAT.Sockets.Thin is
Typ : C.int;
Protocol : C.int) return C.int;
- function C_Strerror
- (Errnum : C.int) return C.Strings.chars_ptr;
-
function C_System
(Command : System.Address) return C.int;
@@ -241,7 +238,6 @@ private
pragma Import (Stdcall, C_Setsockopt, "setsockopt");
pragma Import (Stdcall, C_Shutdown, "shutdown");
pragma Import (Stdcall, C_Socket, "socket");
- pragma Import (C, C_Strerror, "strerror");
pragma Import (C, C_System, "_system");
pragma Import (Stdcall, Socket_Errno, "WSAGetLastError");
pragma Import (Stdcall, Set_Socket_Errno, "WSASetLastError");
diff --git a/gcc/ada/g-socthi-vms.adb b/gcc/ada/g-socthi-vms.adb
index cb2b211d2aa..b9e23ecbfb5 100644
--- a/gcc/ada/g-socthi-vms.adb
+++ b/gcc/ada/g-socthi-vms.adb
@@ -473,19 +473,6 @@ package body GNAT.Sockets.Thin is
function Socket_Error_Message
(Errno : Integer) return C.Strings.chars_ptr
- is
- use type Interfaces.C.Strings.chars_ptr;
-
- C_Msg : C.Strings.chars_ptr;
-
- begin
- C_Msg := C_Strerror (C.int (Errno));
-
- if C_Msg = C.Strings.Null_Ptr then
- return Unknown_System_Error;
- else
- return C_Msg;
- end if;
- end Socket_Error_Message;
+ is separate;
end GNAT.Sockets.Thin;
diff --git a/gcc/ada/g-socthi-vms.ads b/gcc/ada/g-socthi-vms.ads
index 3032b0ec72b..a1bb487e136 100644
--- a/gcc/ada/g-socthi-vms.ads
+++ b/gcc/ada/g-socthi-vms.ads
@@ -187,9 +187,6 @@ package GNAT.Sockets.Thin is
Typ : C.int;
Protocol : C.int) return C.int;
- function C_Strerror
- (Errnum : C.int) return C.Strings.chars_ptr;
-
function C_System
(Command : System.Address) return C.int;
@@ -255,7 +252,6 @@ private
pragma Import (C, C_Select, "DECC$SELECT");
pragma Import (C, C_Setsockopt, "DECC$SETSOCKOPT");
pragma Import (C, C_Shutdown, "DECC$SHUTDOWN");
- pragma Import (C, C_Strerror, "DECC$STRERROR");
pragma Import (C, C_System, "DECC$SYSTEM");
pragma Import (C, Nonreentrant_Gethostbyname, "DECC$GETHOSTBYNAME");
diff --git a/gcc/ada/g-socthi-vxworks.adb b/gcc/ada/g-socthi-vxworks.adb
index 96d0cfca7a3..e6a8ee60644 100644
--- a/gcc/ada/g-socthi-vxworks.adb
+++ b/gcc/ada/g-socthi-vxworks.adb
@@ -489,20 +489,6 @@ package body GNAT.Sockets.Thin is
function Socket_Error_Message
(Errno : Integer) return C.Strings.chars_ptr
- is
- use type Interfaces.C.Strings.chars_ptr;
-
- C_Msg : C.Strings.chars_ptr;
-
- begin
- C_Msg := C_Strerror (C.int (Errno));
-
- if C_Msg = C.Strings.Null_Ptr then
- return Unknown_System_Error;
-
- else
- return C_Msg;
- end if;
- end Socket_Error_Message;
+ is separate;
end GNAT.Sockets.Thin;
diff --git a/gcc/ada/g-socthi-vxworks.ads b/gcc/ada/g-socthi-vxworks.ads
index 08fac05d555..4f92b3a8143 100644
--- a/gcc/ada/g-socthi-vxworks.ads
+++ b/gcc/ada/g-socthi-vxworks.ads
@@ -185,9 +185,6 @@ package GNAT.Sockets.Thin is
Typ : C.int;
Protocol : C.int) return C.int;
- function C_Strerror
- (Errnum : C.int) return C.Strings.chars_ptr;
-
function C_System
(Command : System.Address) return C.int;
@@ -232,6 +229,5 @@ private
pragma Import (C, C_Select, "select");
pragma Import (C, C_Setsockopt, "setsockopt");
pragma Import (C, C_Shutdown, "shutdown");
- pragma Import (C, C_Strerror, "strerror");
pragma Import (C, C_System, "system");
end GNAT.Sockets.Thin;
diff --git a/gcc/ada/g-socthi.adb b/gcc/ada/g-socthi.adb
index b232378fab6..ca797631b08 100644
--- a/gcc/ada/g-socthi.adb
+++ b/gcc/ada/g-socthi.adb
@@ -494,19 +494,6 @@ package body GNAT.Sockets.Thin is
function Socket_Error_Message
(Errno : Integer) return C.Strings.chars_ptr
- is
- use type Interfaces.C.Strings.chars_ptr;
-
- C_Msg : C.Strings.chars_ptr;
-
- begin
- C_Msg := C_Strerror (C.int (Errno));
-
- if C_Msg = C.Strings.Null_Ptr then
- return Unknown_System_Error;
- else
- return C_Msg;
- end if;
- end Socket_Error_Message;
+ is separate;
end GNAT.Sockets.Thin;
diff --git a/gcc/ada/g-socthi.ads b/gcc/ada/g-socthi.ads
index eb690c5b4a8..1f103e89a74 100644
--- a/gcc/ada/g-socthi.ads
+++ b/gcc/ada/g-socthi.ads
@@ -186,9 +186,6 @@ package GNAT.Sockets.Thin is
Typ : C.int;
Protocol : C.int) return C.int;
- function C_Strerror
- (Errnum : C.int) return C.Strings.chars_ptr;
-
function C_System
(Command : System.Address) return C.int;
@@ -257,7 +254,6 @@ private
pragma Import (C, C_Select, "select");
pragma Import (C, C_Setsockopt, "setsockopt");
pragma Import (C, C_Shutdown, "shutdown");
- pragma Import (C, C_Strerror, "strerror");
pragma Import (C, C_System, "system");
pragma Import (C, Nonreentrant_Gethostbyname, "gethostbyname");
diff --git a/gcc/ada/g-sothco.ads b/gcc/ada/g-sothco.ads
index c5636a8f1e3..82003e2ffd5 100644
--- a/gcc/ada/g-sothco.ads
+++ b/gcc/ada/g-sothco.ads
@@ -212,19 +212,45 @@ package GNAT.Sockets.Thin_Common is
C.Strings.Null_Ptr);
-- Arrays of C (char *)
- type Servent is record
- S_Name : C.Strings.chars_ptr;
- S_Aliases : Chars_Ptr_Pointers.Pointer;
- S_Port : C.int;
- S_Proto : C.Strings.chars_ptr;
- end record;
- pragma Convention (C, Servent);
- -- Service entry
+ type Servent is new
+ System.Storage_Elements.Storage_Array (1 .. SOSC.SIZEOF_struct_servent);
+ for Servent'Alignment use 8;
+ -- Service entry. This is an opaque type used only via the following
+ -- accessor functions, because 'struct servent' has different layouts on
+ -- different platforms.
type Servent_Access is access all Servent;
pragma Convention (C, Servent_Access);
-- Access to service entry
+ function Servent_S_Name
+ (E : Servent_Access) return C.Strings.chars_ptr;
+
+ function Servent_S_Aliases
+ (E : Servent_Access) return Chars_Ptr_Pointers.Pointer;
+
+ function Servent_S_Port
+ (E : Servent_Access) return C.int;
+
+ function Servent_S_Proto
+ (E : Servent_Access) return C.Strings.chars_ptr;
+
+ procedure Servent_Set_S_Name
+ (E : Servent_Access;
+ S_Name : C.Strings.chars_ptr);
+
+ procedure Servent_Set_S_Aliases
+ (E : Servent_Access;
+ S_Aliases : Chars_Ptr_Pointers.Pointer);
+
+ procedure Servent_Set_S_Port
+ (E : Servent_Access;
+ S_Port : C.int);
+
+ procedure Servent_Set_S_Proto
+ (E : Servent_Access;
+ S_Proto : C.Strings.chars_ptr);
+
------------------
-- Host entries --
------------------
@@ -335,4 +361,13 @@ private
pragma Import (C, Reset_Socket_Set, "__gnat_reset_socket_set");
pragma Import (C, C_Ioctl, "__gnat_socket_ioctl");
pragma Import (C, Inet_Pton, SOSC.Inet_Pton_Linkname);
+
+ pragma Import (C, Servent_S_Name, "__gnat_servent_s_name");
+ pragma Import (C, Servent_S_Aliases, "__gnat_servent_s_aliases");
+ pragma Import (C, Servent_S_Port, "__gnat_servent_s_port");
+ pragma Import (C, Servent_S_Proto, "__gnat_servent_s_proto");
+ pragma Import (C, Servent_Set_S_Name, "__gnat_servent_set_s_name");
+ pragma Import (C, Servent_Set_S_Aliases, "__gnat_servent_set_s_aliases");
+ pragma Import (C, Servent_Set_S_Port, "__gnat_servent_set_s_port");
+ pragma Import (C, Servent_Set_S_Proto, "__gnat_servent_set_s_proto");
end GNAT.Sockets.Thin_Common;
diff --git a/gcc/ada/g-sttsne-locking.adb b/gcc/ada/g-sttsne-locking.adb
index 622587123ee..c5e39b734b9 100644
--- a/gcc/ada/g-sttsne-locking.adb
+++ b/gcc/ada/g-sttsne-locking.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2007, AdaCore --
+-- Copyright (C) 2007-2009, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -57,8 +57,8 @@ package body GNAT.Sockets.Thin.Task_Safe_NetDB is
-- is too small for the associated data).
procedure Copy_Service_Entry
- (Source_Servent : Servent;
- Target_Servent : out Servent;
+ (Source_Servent : Servent_Access;
+ Target_Servent : Servent_Access;
Target_Buffer : System.Address;
Target_Buffer_Length : C.int;
Result : out C.int);
@@ -194,8 +194,8 @@ package body GNAT.Sockets.Thin.Task_Safe_NetDB is
------------------------
procedure Copy_Service_Entry
- (Source_Servent : Servent;
- Target_Servent : out Servent;
+ (Source_Servent : Servent_Access;
+ Target_Servent : Servent_Access;
Target_Buffer : System.Address;
Target_Buffer_Length : C.int;
Result : out C.int)
@@ -206,14 +206,15 @@ package body GNAT.Sockets.Thin.Task_Safe_NetDB is
Source_Aliases : Chars_Ptr_Array
renames Chars_Ptr_Pointers.Value
- (Source_Servent.S_Aliases, Terminator => C.Strings.Null_Ptr);
+ (Servent_S_Aliases (Source_Servent),
+ Terminator => C.Strings.Null_Ptr);
-- Null-terminated list of aliases (last element of this array is
-- Null_Ptr).
begin
Result := -1;
- Names_Length := C.Strings.Strlen (Source_Servent.S_Name) + 1
- + C.Strings.Strlen (Source_Servent.S_Proto) + 1;
+ Names_Length := C.Strings.Strlen (Servent_S_Name (Source_Servent)) + 1 +
+ C.Strings.Strlen (Servent_S_Proto (Source_Servent)) + 1;
for J in Source_Aliases'Range loop
if Source_Aliases (J) /= C.Strings.Null_Ptr then
@@ -235,6 +236,8 @@ package body GNAT.Sockets.Thin.Task_Safe_NetDB is
Names_Index : size_t := Netdb_Data.Names'First;
-- Index of first available location in Netdb_Data.Names
+ Stored_Name : C.Strings.chars_ptr;
+
begin
if Netdb_Data'Size / 8 > Target_Buffer_Length then
return;
@@ -243,26 +246,29 @@ package body GNAT.Sockets.Thin.Task_Safe_NetDB is
-- Copy service name
Store_Name
- (C.Strings.Value (Source_Servent.S_Name),
+ (C.Strings.Value (Servent_S_Name (Source_Servent)),
Netdb_Data.Names, Names_Index,
- Target_Servent.S_Name);
+ Stored_Name);
+ Servent_Set_S_Name (Target_Servent, Stored_Name);
-- Copy aliases (null-terminated string pointer array)
- Target_Servent.S_Aliases :=
- Netdb_Data.Aliases_List
- (Netdb_Data.Aliases_List'First)'Unchecked_Access;
+ Servent_Set_S_Aliases
+ (Target_Servent,
+ Netdb_Data.Aliases_List
+ (Netdb_Data.Aliases_List'First)'Unchecked_Access);
-- Copy port number
- Target_Servent.S_Port := Source_Servent.S_Port;
+ Servent_Set_S_Port (Target_Servent, Servent_S_Port (Source_Servent));
-- Copy protocol name
Store_Name
- (C.Strings.Value (Source_Servent.S_Proto),
+ (C.Strings.Value (Servent_S_Proto (Source_Servent)),
Netdb_Data.Names, Names_Index,
- Target_Servent.S_Proto);
+ Stored_Name);
+ Servent_Set_S_Proto (Target_Servent, Stored_Name);
for J in Netdb_Data.Aliases_List'Range loop
if J = Netdb_Data.Aliases_List'Last then
@@ -377,11 +383,14 @@ package body GNAT.Sockets.Thin.Task_Safe_NetDB is
goto Unlock_Return;
end if;
- -- Now copy the data to the user-provided buffer
+ -- Now copy the data to the user-provided buffer. We convert Ret to
+ -- type Servent_Access using the .all'Unchecked_Access trick to avoid
+ -- an accessibility check. Ret could be pointing to a nested variable,
+ -- and we don't want to raise an exception in that case.
Copy_Service_Entry
- (Source_Servent => SE.all,
- Target_Servent => Ret.all,
+ (Source_Servent => SE,
+ Target_Servent => Ret.all'Unchecked_Access,
Target_Buffer => Buf,
Target_Buffer_Length => Buflen,
Result => Result);
@@ -414,11 +423,12 @@ package body GNAT.Sockets.Thin.Task_Safe_NetDB is
goto Unlock_Return;
end if;
- -- Now copy the data to the user-provided buffer
+ -- Now copy the data to the user-provided buffer. See Safe_Getservbyname
+ -- for comment regarding .all'Unchecked_Access.
Copy_Service_Entry
- (Source_Servent => SE.all,
- Target_Servent => Ret.all,
+ (Source_Servent => SE,
+ Target_Servent => Ret.all'Unchecked_Access,
Target_Buffer => Buf,
Target_Buffer_Length => Buflen,
Result => Result);
diff --git a/gcc/ada/g-trasym-vms-alpha.adb b/gcc/ada/g-trasym-vms-alpha.adb
index adfa8f83d4e..c58c5610bfd 100644
--- a/gcc/ada/g-trasym-vms-alpha.adb
+++ b/gcc/ada/g-trasym-vms-alpha.adb
@@ -217,11 +217,9 @@ package body GNAT.Traceback.Symbolic is
System.Soft_Links.Lock_Task.all;
for J in Traceback'Range loop
- if J = Traceback'Last then
- Return_Address := Address_Zero;
- else
- Return_Address := PC_For (Traceback (J + 1));
- end if;
+ Return_Address :=
+ (if J = Traceback'Last then Address_Zero
+ else PC_For (Traceback (J + 1)));
Symbolize
(Status,
diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in
index 02887029b22..d57c1f0032c 100644
--- a/gcc/ada/gcc-interface/Make-lang.in
+++ b/gcc/ada/gcc-interface/Make-lang.in
@@ -116,60 +116,223 @@ GNAT1_C_OBJS = ada/b_gnat1.o ada/adadecode.o ada/adaint.o ada/cstreams.o \
# Object files from Ada sources that are used by gnat1
-GNAT_ADA_OBJS = ada/s-bitops.o ada/ada.o ada/a-charac.o ada/a-chlat1.o ada/a-except.o \
- ada/a-elchha.o ada/a-ioexce.o \
- ada/s-memory.o ada/s-carun8.o ada/s-casuti.o ada/s-strcom.o ada/s-strhas.o \
- ada/s-purexc.o ada/s-htable.o ada/s-traceb.o ada/s-mastop.o ada/ali.o \
- ada/alloc.o ada/atree.o ada/butil.o ada/casing.o ada/checks.o ada/comperr.o \
- ada/csets.o ada/cstand.o ada/debug.o ada/debug_a.o ada/einfo.o ada/elists.o \
- ada/errout.o ada/erroutc.o ada/err_vars.o ada/eval_fat.o ada/exp_attr.o \
- ada/exp_ch11.o ada/exp_ch12.o ada/exp_ch13.o ada/exp_ch2.o ada/exp_ch3.o \
- ada/exp_ch4.o ada/exp_ch5.o ada/exp_ch6.o ada/exp_ch7.o ada/exp_ch8.o \
- ada/exp_ch9.o ada/exp_code.o ada/exp_dbug.o ada/exp_disp.o ada/exp_atag.o \
- ada/exp_dist.o ada/exp_fixd.o ada/exp_aggr.o ada/exp_imgv.o ada/exp_intr.o \
- ada/exp_pakd.o ada/exp_prag.o ada/exp_sel.o ada/exp_smem.o ada/exp_strm.o \
- ada/exp_tss.o ada/exp_util.o ada/exp_vfpt.o ada/expander.o ada/fname.o \
- ada/fname-uf.o ada/fmap.o ada/freeze.o ada/frontend.o ada/gnat.o \
- ada/g-byorma.o \
- ada/g-hesora.o ada/g-htable.o ada/s-os_lib.o \
- ada/g-speche.o ada/g-spchge.o ada/g-u3spch.o ada/s-string.o \
- ada/s-utf_32.o ada/s-crc32.o ada/get_targ.o \
- ada/get_scos.o \
- ada/gnatvsn.o ada/hlo.o ada/hostparm.o ada/impunit.o ada/interfac.o \
- ada/itypes.o ada/inline.o ada/krunch.o ada/lib.o ada/layout.o \
- ada/lib-load.o ada/lib-util.o ada/lib-xref.o ada/lib-writ.o ada/live.o \
- ada/namet.o ada/namet-sp.o \
- ada/nlists.o ada/nmake.o ada/opt.o ada/osint.o ada/osint-c.o \
- ada/output.o \
- ada/par_sco.o \
- ada/par.o ada/prep.o ada/prepcomp.o ada/put_scos.o \
- ada/repinfo.o ada/restrict.o \
- ada/rident.o ada/rtsfind.o \
- ada/s-addope.o ada/s-assert.o ada/s-parame.o ada/s-stache.o \
- ada/s-stalib.o ada/s-imgenu.o ada/s-imenne.o ada/s-stoele.o ada/s-soflin.o \
- ada/s-except.o ada/s-exctab.o \
- ada/s-secsta.o ada/s-strops.o ada/s-sopco3.o ada/s-sopco4.o ada/s-sopco5.o \
- ada/s-traent.o ada/s-wchcnv.o ada/s-wchcon.o ada/s-wchjis.o \
- ada/s-conca2.o ada/s-conca3.o ada/s-conca4.o ada/s-conca5.o \
- ada/s-conca6.o ada/s-conca7.o ada/s-conca8.o ada/s-conca9.o \
- ada/s-unstyp.o ada/scans.o ada/scng.o ada/scn.o ada/sdefault.o ada/sem.o \
- ada/scos.o \
- ada/sem_aggr.o ada/sem_attr.o ada/sem_aux.o \
- ada/sem_cat.o ada/sem_ch10.o ada/sem_ch11.o \
- ada/sem_ch12.o ada/sem_ch13.o ada/sem_ch2.o ada/sem_ch3.o ada/sem_ch4.o \
- ada/sem_ch5.o ada/sem_ch6.o ada/sem_ch7.o ada/sem_ch8.o ada/sem_ch9.o \
- ada/sem_case.o ada/sem_disp.o ada/sem_dist.o ada/sem_elab.o ada/sem_elim.o \
- ada/sem_eval.o ada/sem_intr.o ada/sem_mech.o ada/sem_prag.o ada/sem_res.o \
- ada/sem_scil.o ada/sem_smem.o ada/sem_type.o ada/sem_util.o ada/sem_vfpt.o \
- ada/sem_warn.o ada/sinfo-cn.o ada/sinfo.o ada/sinput.o ada/sinput-d.o \
- ada/sinput-l.o ada/snames.o ada/sprint.o ada/stand.o ada/stringt.o \
- ada/style.o ada/styleg.o ada/switch.o ada/switch-c.o \
- ada/stylesw.o ada/validsw.o ada/system.o ada/table.o ada/targparm.o \
- ada/tbuild.o ada/tree_gen.o ada/tree_in.o \
- ada/tree_io.o ada/treepr.o ada/treeprs.o \
- ada/ttypef.o ada/ttypes.o ada/types.o ada/uintp.o ada/uname.o ada/urealp.o \
- ada/usage.o ada/widechar.o ada/s-crtl.o ada/seh_init.o ada/targext.o \
- ada/s-restri.o
+GNAT_ADA_OBJS = \
+ ada/a-charac.o \
+ ada/a-chlat1.o \
+ ada/a-elchha.o \
+ ada/a-except.o \
+ ada/a-ioexce.o \
+ ada/ada.o \
+ ada/ali.o \
+ ada/alloc.o \
+ ada/atree.o \
+ ada/butil.o \
+ ada/casing.o \
+ ada/checks.o \
+ ada/comperr.o \
+ ada/csets.o \
+ ada/cstand.o \
+ ada/debug.o \
+ ada/debug_a.o \
+ ada/einfo.o \
+ ada/elists.o \
+ ada/err_vars.o \
+ ada/errout.o \
+ ada/erroutc.o \
+ ada/eval_fat.o \
+ ada/exp_aggr.o \
+ ada/exp_atag.o \
+ ada/exp_attr.o \
+ ada/exp_ch11.o \
+ ada/exp_ch12.o \
+ ada/exp_ch13.o \
+ ada/exp_ch2.o \
+ ada/exp_ch3.o \
+ ada/exp_ch4.o \
+ ada/exp_ch5.o \
+ ada/exp_ch6.o \
+ ada/exp_ch7.o \
+ ada/exp_ch8.o \
+ ada/exp_ch9.o \
+ ada/exp_code.o \
+ ada/exp_dbug.o \
+ ada/exp_disp.o \
+ ada/exp_dist.o \
+ ada/exp_fixd.o \
+ ada/exp_imgv.o \
+ ada/exp_intr.o \
+ ada/exp_pakd.o \
+ ada/exp_prag.o \
+ ada/exp_sel.o \
+ ada/exp_smem.o \
+ ada/exp_strm.o \
+ ada/exp_tss.o \
+ ada/exp_util.o \
+ ada/exp_vfpt.o \
+ ada/expander.o \
+ ada/fmap.o \
+ ada/fname-uf.o \
+ ada/fname.o \
+ ada/freeze.o \
+ ada/frontend.o \
+ ada/g-byorma.o \
+ ada/g-hesora.o \
+ ada/g-htable.o \
+ ada/g-spchge.o \
+ ada/g-speche.o \
+ ada/g-u3spch.o \
+ ada/get_scos.o \
+ ada/get_targ.o \
+ ada/gnat.o \
+ ada/gnatvsn.o \
+ ada/hlo.o \
+ ada/hostparm.o \
+ ada/impunit.o \
+ ada/inline.o \
+ ada/interfac.o \
+ ada/itypes.o \
+ ada/krunch.o \
+ ada/layout.o \
+ ada/lib-load.o \
+ ada/lib-util.o \
+ ada/lib-writ.o \
+ ada/lib-xref.o \
+ ada/lib.o \
+ ada/live.o \
+ ada/namet-sp.o \
+ ada/namet.o \
+ ada/nlists.o \
+ ada/nmake.o \
+ ada/opt.o \
+ ada/osint-c.o \
+ ada/osint.o \
+ ada/output.o \
+ ada/par.o \
+ ada/par_sco.o \
+ ada/prep.o \
+ ada/prepcomp.o \
+ ada/put_scos.o \
+ ada/repinfo.o \
+ ada/restrict.o \
+ ada/rident.o \
+ ada/rtsfind.o \
+ ada/s-addope.o \
+ ada/s-assert.o \
+ ada/s-bitops.o \
+ ada/s-carun8.o \
+ ada/s-casuti.o \
+ ada/s-conca2.o \
+ ada/s-conca3.o \
+ ada/s-conca4.o \
+ ada/s-conca5.o \
+ ada/s-conca6.o \
+ ada/s-conca7.o \
+ ada/s-conca8.o \
+ ada/s-conca9.o \
+ ada/s-crc32.o \
+ ada/s-crtl.o \
+ ada/s-except.o \
+ ada/s-exctab.o \
+ ada/s-htable.o \
+ ada/s-imenne.o \
+ ada/s-imgenu.o \
+ ada/s-mastop.o \
+ ada/s-memory.o \
+ ada/s-os_lib.o \
+ ada/s-parame.o \
+ ada/s-purexc.o \
+ ada/s-restri.o \
+ ada/s-secsta.o \
+ ada/s-soflin.o \
+ ada/s-sopco3.o \
+ ada/s-sopco4.o \
+ ada/s-sopco5.o \
+ ada/s-stache.o \
+ ada/s-stalib.o \
+ ada/s-stoele.o \
+ ada/s-strcom.o \
+ ada/s-strhas.o \
+ ada/s-string.o \
+ ada/s-strops.o \
+ ada/s-traceb.o \
+ ada/s-traent.o \
+ ada/s-unstyp.o \
+ ada/s-utf_32.o \
+ ada/s-wchcnv.o \
+ ada/s-wchcon.o \
+ ada/s-wchjis.o \
+ ada/scans.o \
+ ada/scn.o \
+ ada/scng.o \
+ ada/scos.o \
+ ada/sdefault.o \
+ ada/seh_init.o \
+ ada/sem.o \
+ ada/sem_aggr.o \
+ ada/sem_attr.o \
+ ada/sem_aux.o \
+ ada/sem_case.o \
+ ada/sem_cat.o \
+ ada/sem_ch10.o \
+ ada/sem_ch11.o \
+ ada/sem_ch12.o \
+ ada/sem_ch13.o \
+ ada/sem_ch2.o \
+ ada/sem_ch3.o \
+ ada/sem_ch4.o \
+ ada/sem_ch5.o \
+ ada/sem_ch6.o \
+ ada/sem_ch7.o \
+ ada/sem_ch8.o \
+ ada/sem_ch9.o \
+ ada/sem_disp.o \
+ ada/sem_dist.o \
+ ada/sem_elab.o \
+ ada/sem_elim.o \
+ ada/sem_eval.o \
+ ada/sem_intr.o \
+ ada/sem_mech.o \
+ ada/sem_prag.o \
+ ada/sem_res.o \
+ ada/sem_scil.o \
+ ada/sem_smem.o \
+ ada/sem_type.o \
+ ada/sem_util.o \
+ ada/sem_vfpt.o \
+ ada/sem_warn.o \
+ ada/sinfo-cn.o \
+ ada/sinfo.o \
+ ada/sinput-d.o \
+ ada/sinput-l.o \
+ ada/sinput.o \
+ ada/snames.o \
+ ada/sprint.o \
+ ada/stand.o \
+ ada/stringt.o \
+ ada/style.o \
+ ada/styleg.o \
+ ada/stylesw.o \
+ ada/switch-c.o \
+ ada/switch.o \
+ ada/system.o \
+ ada/table.o \
+ ada/targext.o \
+ ada/targparm.o \
+ ada/tbuild.o \
+ ada/tree_gen.o \
+ ada/tree_in.o \
+ ada/tree_io.o \
+ ada/treepr.o \
+ ada/treeprs.o \
+ ada/ttypef.o \
+ ada/ttypes.o \
+ ada/types.o \
+ ada/uintp.o \
+ ada/uname.o \
+ ada/urealp.o \
+ ada/usage.o \
+ ada/validsw.o \
+ ada/widechar.o
# Object files for gnat executables
GNAT1_ADA_OBJS = $(GNAT_ADA_OBJS) ada/back_end.o ada/gnat1drv.o
@@ -1204,10 +1367,11 @@ ada/back_end.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/sinput.adb ada/snames.ads ada/stand.ads ada/stringt.ads \
ada/switch.ads ada/switch-c.ads ada/system.ads ada/s-exctab.ads \
ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \
- ada/s-parame.ads ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads \
- ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
- ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
+ ada/s-parame.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \
+ ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
+ ada/table.ads ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads \
+ ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \
+ ada/urealp.ads ada/widechar.ads
ada/bcheck.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/ali.ads ada/ali-util.ads ada/ali-util.adb \
@@ -1267,10 +1431,10 @@ ada/bindusg.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/bindusg.ads ada/bindusg.adb \
ada/debug.ads ada/hostparm.ads ada/namet.ads ada/opt.ads ada/osint.ads \
ada/output.ads ada/system.ads ada/s-exctab.ads ada/s-memory.ads \
- ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/tree_io.ads ada/types.ads ada/unchconv.ads \
- ada/unchdeal.ads
+ ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads ada/s-stoele.ads \
+ ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
+ ada/types.ads ada/unchconv.ads ada/unchdeal.ads
ada/butil.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/butil.ads ada/butil.adb \
@@ -1499,28 +1663,24 @@ ada/exp_aggr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_atag.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \
- ada/casing.ads ada/checks.ads ada/csets.ads ada/debug.ads ada/einfo.ads \
- ada/einfo.adb ada/elists.ads ada/elists.adb ada/err_vars.ads \
- ada/errout.ads ada/erroutc.ads ada/exp_aggr.ads ada/exp_atag.ads \
- ada/exp_atag.adb ada/exp_ch6.ads ada/exp_ch7.ads ada/exp_dist.ads \
- ada/exp_tss.ads ada/exp_util.ads ada/exp_util.adb ada/fname.ads \
- ada/fname-uf.ads ada/get_targ.ads ada/gnat.ads ada/g-htable.ads \
- ada/hostparm.ads ada/inline.ads ada/itypes.ads ada/lib.ads \
+ ada/casing.ads ada/csets.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \
+ ada/elists.ads ada/elists.adb ada/err_vars.ads ada/errout.ads \
+ ada/erroutc.ads ada/exp_atag.ads ada/exp_atag.adb ada/exp_dist.ads \
+ ada/exp_tss.ads ada/exp_util.ads ada/fname.ads ada/fname-uf.ads \
+ ada/gnat.ads ada/g-htable.ads ada/hostparm.ads ada/lib.ads \
ada/lib-load.ads ada/namet.ads ada/nlists.ads ada/nlists.adb \
ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads ada/restrict.ads \
ada/rident.ads ada/rtsfind.ads ada/rtsfind.adb ada/sem.ads \
- ada/sem_aux.ads ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_dist.ads \
- ada/sem_eval.ads ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads \
- ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
- ada/snames.ads ada/stand.ads ada/stringt.ads ada/system.ads \
- ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \
- ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-soflin.ads \
- ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \
- ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
- ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \
- ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \
+ ada/sem_aux.ads ada/sem_ch7.ads ada/sem_dist.ads ada/sem_util.ads \
+ ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
+ ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \
+ ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
+ ada/s-rident.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \
+ ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \
+ ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
+ ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/types.ads \
ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \
- ada/unchdeal.ads ada/urealp.ads ada/validsw.ads
+ ada/unchdeal.ads ada/urealp.ads
ada/exp_attr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \
@@ -2185,10 +2345,10 @@ ada/fmap.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/gnat.ads ada/g-htable.ads ada/hostparm.ads ada/namet.ads \
ada/opt.ads ada/osint.ads ada/output.ads ada/system.ads \
ada/s-exctab.ads ada/s-htable.ads ada/s-htable.adb ada/s-memory.ads \
- ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads ada/s-strhas.ads \
- ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
- ada/table.ads ada/table.adb ada/tree_io.ads ada/types.ads \
- ada/unchconv.ads ada/unchdeal.ads
+ ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads ada/s-stoele.ads \
+ ada/s-stoele.adb ada/s-strhas.ads ada/s-string.ads ada/s-traent.ads \
+ ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
+ ada/tree_io.ads ada/types.ads ada/unchconv.ads ada/unchdeal.ads
ada/fname-uf.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/casing.ads ada/debug.ads \
@@ -2197,10 +2357,11 @@ ada/fname-uf.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/namet.ads ada/opt.ads ada/osint.ads ada/output.ads ada/rident.ads \
ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-htable.adb \
ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \
- ada/s-stalib.ads ada/s-strhas.ads ada/s-string.ads ada/s-traent.ads \
- ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
- ada/targparm.ads ada/tree_io.ads ada/types.ads ada/uname.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/widechar.ads
+ ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-strhas.ads \
+ ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
+ ada/table.ads ada/table.adb ada/targparm.ads ada/tree_io.ads \
+ ada/types.ads ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \
+ ada/widechar.ads
ada/fname.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/debug.ads ada/fname.ads \
@@ -2489,9 +2650,10 @@ ada/lib-util.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/lib.ads ada/lib-util.ads ada/lib-util.adb ada/namet.ads ada/opt.ads \
ada/osint.ads ada/osint-c.ads ada/output.ads ada/system.ads \
ada/s-exctab.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
- ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
- ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
- ada/types.ads ada/unchconv.ads ada/unchdeal.ads
+ ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
+ ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
+ ada/table.adb ada/tree_io.ads ada/types.ads ada/unchconv.ads \
+ ada/unchdeal.ads
ada/lib-writ.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/ali.ads ada/alloc.ads ada/atree.ads ada/atree.adb \
@@ -2531,10 +2693,10 @@ ada/lib-xref.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/sinput.adb ada/snames.ads ada/stand.ads ada/stringt.ads \
ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \
ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \
- ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
- ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
- ada/types.ads ada/uintp.ads ada/uintp.adb ada/unchconv.ads \
- ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
+ ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
+ ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
+ ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uintp.adb \
+ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
ada/lib.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads ada/a-uncdea.ads \
ada/alloc.ads ada/atree.ads ada/atree.adb ada/casing.ads ada/debug.ads \
@@ -2704,10 +2866,11 @@ ada/par_sco.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/snames.ads ada/stand.ads ada/stringt.ads ada/system.ads \
ada/s-exctab.ads ada/s-htable.ads ada/s-htable.adb ada/s-imenne.ads \
ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads \
- ada/s-strhas.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
- ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
- ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
+ ada/s-stoele.ads ada/s-stoele.adb ada/s-strhas.ads ada/s-string.ads \
+ ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
+ ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uintp.adb \
+ ada/uname.ads ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \
+ ada/widechar.ads
ada/prep.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/casing.ads ada/csets.ads \
@@ -3899,10 +4062,10 @@ ada/sinput-d.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/hostparm.ads ada/namet.ads ada/opt.ads ada/osint.ads \
ada/osint-c.ads ada/output.ads ada/sinput.ads ada/sinput-d.ads \
ada/sinput-d.adb ada/system.ads ada/s-exctab.ads ada/s-memory.ads \
- ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/tree_io.ads ada/types.ads ada/unchconv.ads \
- ada/unchdeal.ads
+ ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads ada/s-stoele.ads \
+ ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
+ ada/types.ads ada/unchconv.ads ada/unchdeal.ads
ada/sinput-l.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/atree.adb \
@@ -3953,17 +4116,17 @@ ada/sprint.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/hostparm.ads ada/interfac.ads ada/lib.ads ada/lib.adb \
ada/lib-list.adb ada/lib-sort.adb ada/namet.ads ada/namet.adb \
ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/opt.ads ada/output.ads \
- ada/output.adb ada/rtsfind.ads ada/sem_util.ads ada/sinfo.ads \
- ada/sinfo.adb ada/sinput.ads ada/sinput.adb ada/sinput-d.ads \
- ada/snames.ads ada/sprint.ads ada/sprint.adb ada/stand.ads \
- ada/stringt.ads ada/stringt.adb ada/system.ads ada/s-exctab.ads \
- ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \
- ada/s-parame.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \
- ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uintp.adb \
- ada/uname.ads ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \
- ada/urealp.adb ada/widechar.ads
+ ada/output.adb ada/rtsfind.ads ada/sem_eval.ads ada/sem_util.ads \
+ ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \
+ ada/sinput-d.ads ada/snames.ads ada/sprint.ads ada/sprint.adb \
+ ada/stand.ads ada/stringt.ads ada/stringt.adb ada/system.ads \
+ ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \
+ ada/s-os_lib.ads ada/s-parame.ads ada/s-secsta.ads ada/s-soflin.ads \
+ ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \
+ ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
+ ada/table.ads ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads \
+ ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \
+ ada/urealp.ads ada/urealp.adb ada/widechar.ads
ada/stand.o : ada/ada.ads ada/a-unccon.ads ada/a-uncdea.ads ada/stand.ads \
ada/stand.adb ada/system.ads ada/s-exctab.ads ada/s-os_lib.ads \
@@ -4090,10 +4253,11 @@ ada/tree_gen.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/sem_aux.ads ada/sinfo.ads ada/sinput.ads ada/snames.ads \
ada/stand.ads ada/stringt.ads ada/system.ads ada/s-exctab.ads \
ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads \
- ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
- ada/table.ads ada/table.adb ada/tree_gen.ads ada/tree_gen.adb \
- ada/tree_in.ads ada/tree_io.ads ada/types.ads ada/uintp.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads
+ ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \
+ ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
+ ada/tree_gen.ads ada/tree_gen.adb ada/tree_in.ads ada/tree_io.ads \
+ ada/types.ads ada/uintp.ads ada/unchconv.ads ada/unchdeal.ads \
+ ada/urealp.ads
ada/tree_in.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/casing.ads \
@@ -4192,10 +4356,11 @@ ada/usage.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/debug.ads ada/hostparm.ads \
ada/namet.ads ada/opt.ads ada/osint.ads ada/output.ads ada/rident.ads \
ada/system.ads ada/s-exctab.ads ada/s-memory.ads ada/s-os_lib.ads \
- ada/s-parame.ads ada/s-rident.ads ada/s-stalib.ads ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/targparm.ads ada/tree_io.ads ada/types.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/usage.ads ada/usage.adb
+ ada/s-parame.ads ada/s-rident.ads ada/s-stalib.ads ada/s-stoele.ads \
+ ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \
+ ada/tree_io.ads ada/types.ads ada/unchconv.ads ada/unchdeal.ads \
+ ada/usage.ads ada/usage.adb
ada/validsw.o : ada/ada.ads ada/a-unccon.ads ada/a-uncdea.ads \
ada/hostparm.ads ada/opt.ads ada/system.ads ada/s-exctab.ads \
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index c9221fb5022..975db0f2b7d 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -190,6 +190,11 @@ TOOLSCASE =
MULTISUBDIR =
RTSDIR = rts$(subst /,_,$(MULTISUBDIR))
+# Link flags used to build gnat tools. By default we prefer to statically
+# link with libgcc to avoid a dependency on shared libgcc (which is tricky
+# to deal with as it may conflict with the libgcc provided by the system).
+GCC_LINK_FLAGS=-static-libgcc
+
# End of variables for you to override.
all: all.indirect
@@ -370,18 +375,6 @@ GNATLIB_SHARED = gnatlib
# default value for gnatmake's target dependent file
MLIB_TGT = mlib-tgt
-# By default, do not distribute prefix.o (in libgccprefix), since it is only
-# needed by external GNAT tools such as gnatdist and Glide.
-# Override this variable on native platforms when needed.
-PREFIX_OBJS =
-
-# To avoid duplicate code, use this variable to set PREFIX_OBJS when needed:
-PREFIX_REAL_OBJS = ../prefix.o \
- ../../libiberty/concat.o \
- ../../libiberty/xmalloc.o \
- ../../libiberty/xstrdup.o \
- ../../libiberty/xexit.o
-
# By default, build socket support units. On platforms that do not support
# sockets, reset this variable to empty and add DUMMY_SOCKETS_TARGET_PAIRS
# to LIBGNAT_TARGET_PAIRS.
@@ -934,7 +927,6 @@ ifeq ($(strip $(filter-out sparc% sun solaris%,$(targ))),)
SO_OPTS = -Wl,-h,
GNATLIB_SHARED = gnatlib-shared-dual
GMEM_LIB = gmemlib
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
ifeq ($(strip $(filter-out pthread PTHREAD,$(THREAD_KIND))),)
@@ -993,7 +985,6 @@ ifeq ($(strip $(filter-out %86 solaris2%,$(arch) $(osys))),)
SO_OPTS = -Wl,-h,
GNATLIB_SHARED = gnatlib-shared-dual
GMEM_LIB = gmemlib
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1065,7 +1056,6 @@ ifeq ($(strip $(filter-out %86 linux%,$(arch) $(osys))),)
GNATLIB_SHARED = gnatlib-shared-dual
GMEM_LIB = gmemlib
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1094,7 +1084,6 @@ ifeq ($(strip $(filter-out %86 kfreebsd%,$(arch) $(osys))),)
THREADSLIB = -lpthread
GNATLIB_SHARED = gnatlib-shared-dual
GMEM_LIB = gmemlib
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1123,7 +1112,6 @@ ifeq ($(strip $(filter-out x86_64 kfreebsd%,$(arch) $(osys))),)
THREADSLIB = -lpthread
GNATLIB_SHARED = gnatlib-shared-dual
GMEM_LIB = gmemlib
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1150,7 +1138,6 @@ ifeq ($(strip $(filter-out %86 freebsd%,$(arch) $(osys))),)
EH_MECHANISM=-gcc
THREADSLIB= -lpthread
GMEM_LIB = gmemlib
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1198,7 +1185,6 @@ ifeq ($(strip $(filter-out s390% linux%,$(arch) $(osys))),)
EH_MECHANISM=-gcc
THREADSLIB = -lpthread
GNATLIB_SHARED = gnatlib-shared-dual
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1248,7 +1234,6 @@ ifeq ($(strip $(filter-out mips sgi irix%,$(targ))),)
TOOLS_TARGET_PAIRS = mlib-tgt-specific.adb<mlib-tgt-specific-irix.adb
TGT_LIB = -lexc
MISCLIB = -lexc
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
GMEM_LIB = gmemlib
endif
@@ -1270,7 +1255,6 @@ ifeq ($(strip $(filter-out hppa% hp hpux10%,$(targ))),)
system.ads<system-hpux.ads
EH_MECHANISM=-gcc
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
endif
ifeq ($(strip $(filter-out hppa% hp hpux11%,$(targ))),)
@@ -1295,7 +1279,6 @@ ifeq ($(strip $(filter-out hppa% hp hpux11%,$(targ))),)
GMEM_LIB = gmemlib
soext = .sl
SO_OPTS = -Wl,+h,
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
GNATLIB_SHARED = gnatlib-shared-dual
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1330,7 +1313,6 @@ ifeq ($(strip $(filter-out ibm aix%,$(manu) $(osys))),)
endif
THREADSLIB = -lpthreads
- PREFIX_OBJS=$(PREFIX_REAL_OBJS)
TOOLS_TARGET_PAIRS = \
mlib-tgt-specific.adb<mlib-tgt-specific-aix.adb \
@@ -1364,7 +1346,6 @@ ifeq ($(strip $(filter-out lynxos,$(osys))),)
g-trasym.adb<g-trasym-unimplemented.adb \
system.ads<system-lynxos-x86.ads
- PREFIX_OBJS=$(PREFIX_REAL_OBJS)
else
LIBGNAT_TARGET_PAIRS = \
@@ -1425,7 +1406,6 @@ ifeq ($(strip $(filter-out alpha% dec osf%,$(targ))),)
EH_MECHANISM=-gcc
GMEM_LIB=gmemlib
THREADSLIB = -lpthread -lmach -lexc -lrt
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
GNATLIB_SHARED = gnatlib-shared-default
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1503,7 +1483,6 @@ ifeq ($(strip $(filter-out alpha64 ia64 dec hp vms% openvms% alphavms%,$(targ)))
i-cstrea.adb<i-cstrea-vms.adb \
memtrack.adb<memtrack-vms_64.adb \
s-auxdec.ads<s-auxdec-vms_64.ads \
- s-crtl.ads<s-crtl-vms_64.ads \
s-inmaop.adb<s-inmaop-vms.adb \
s-interr.adb<s-interr-vms.adb \
s-intman.adb<s-intman-vms.adb \
@@ -1640,7 +1619,6 @@ ifeq ($(strip $(filter-out cygwin32% mingw32% pe,$(osys))),)
indepsw.adb<indepsw-mingw.adb
GMEM_LIB = gmemlib
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
EXTRA_GNATTOOLS = ../../gnatdll$(exeext)
EXTRA_GNATMAKE_OBJS = mdll.o mdll-utl.o mdll-fil.o
soext = .dll
@@ -1667,7 +1645,6 @@ ifeq ($(strip $(filter-out mips linux%,$(arch) $(osys))),)
THREADSLIB = -lpthread
GNATLIB_SHARED = gnatlib-shared-dual
GMEM_LIB = gmemlib
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1710,7 +1687,6 @@ ifeq ($(strip $(filter-out mipsel linux%,$(arch) $(osys))),)
THREADSLIB = -lpthread
GNATLIB_SHARED = gnatlib-shared-dual
GMEM_LIB = gmemlib
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1753,7 +1729,6 @@ ifeq ($(strip $(filter-out mips64el linux%,$(arch) $(osys))),)
THREADSLIB = -lpthread
GNATLIB_SHARED = gnatlib-shared-dual
GMEM_LIB = gmemlib
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1814,7 +1789,6 @@ ifeq ($(strip $(filter-out powerpc% linux%,$(arch) $(osys))),)
THREADSLIB = -lpthread
GNATLIB_SHARED = gnatlib-shared-dual
GMEM_LIB = gmemlib
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1858,7 +1832,6 @@ ifeq ($(strip $(filter-out sparc% linux%,$(arch) $(osys))),)
THREADSLIB = -lpthread
GNATLIB_SHARED = gnatlib-shared-dual
GMEM_LIB = gmemlib
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1889,7 +1862,6 @@ ifeq ($(strip $(filter-out hppa% linux%,$(arch) $(osys))),)
THREADSLIB = -lpthread
GNATLIB_SHARED = gnatlib-shared-dual
GMEM_LIB = gmemlib
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1919,7 +1891,6 @@ ifeq ($(strip $(filter-out sh4% linux%,$(arch) $(osys))),)
THREADSLIB = -lpthread
GNATLIB_SHARED = gnatlib-shared-dual
GMEM_LIB = gmemlib
- PREFIX_OBJS = $(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1951,7 +1922,6 @@ ifeq ($(strip $(filter-out %ia64 linux%,$(arch) $(osys))),)
THREADSLIB=-lpthread
GNATLIB_SHARED=gnatlib-shared-dual
GMEM_LIB = gmemlib
- PREFIX_OBJS=$(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -1977,7 +1947,6 @@ ifeq ($(strip $(filter-out ia64% hp hpux%,$(targ))),)
GMEM_LIB = gmemlib
soext = .sl
SO_OPTS = -Wl,+h,
- PREFIX_OBJS=$(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -2008,7 +1977,6 @@ ifeq ($(strip $(filter-out alpha% linux%,$(arch) $(osys))),)
MISCLIB=
THREADSLIB=-lpthread
GNATLIB_SHARED=gnatlib-shared-dual
- PREFIX_OBJS=$(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -2041,7 +2009,6 @@ ifeq ($(strip $(filter-out %x86_64 linux%,$(arch) $(osys))),)
THREADSLIB=-lpthread
GNATLIB_SHARED=gnatlib-shared-dual
GMEM_LIB = gmemlib
- PREFIX_OBJS=$(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
endif
@@ -2114,9 +2081,9 @@ ifeq ($(strip $(filter-out darwin%,$(osys))),)
SO_OPTS = -Wl,-flat_namespace -shared-libgcc
RANLIB = ranlib -c
GMEM_LIB = gmemlib
- PREFIX_OBJS=$(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
soext = .dylib
+ GCC_LINK_FLAGS=
endif
ifneq ($(EH_MECHANISM),)
@@ -2146,15 +2113,16 @@ endif
# while GNATRTL_OBJS lists the object files compiled from Ada sources that
# go into the directory. The pthreads emulation is built in the threads
# subdirectory and copied.
-LIBGNAT_SRCS = adaint.c adaint.h argv.c cio.c cstreams.c \
- errno.c exit.c cal.c ctrl_c.c env.c env.h arit64.c \
- raise.h raise.c sysdep.c aux-io.c init.c initialize.c seh_init.c \
- final.c tracebak.c tb-alvms.c tb-alvxw.c tb-gcc.c expect.c mkdir.c \
- socket.c gsocket.h targext.c $(EXTRA_LIBGNAT_SRCS)
+LIBGNAT_SRCS = adadecode.c adadecode.h adaint.c adaint.h \
+ argv.c cio.c cstreams.c errno.c exit.c cal.c ctrl_c.c env.c env.h \
+ arit64.c raise.h raise.c sysdep.c aux-io.c init.c initialize.c \
+ seh_init.c final.c tracebak.c tb-alvms.c tb-alvxw.c tb-gcc.c \
+ expect.c mkdir.c socket.c gsocket.h targext.c $(EXTRA_LIBGNAT_SRCS)
-LIBGNAT_OBJS = adaint.o argv.o cio.o cstreams.o ctrl_c.o errno.o exit.o env.o \
- raise.o sysdep.o aux-io.o init.o initialize.o seh_init.o cal.o arit64.o \
- final.o tracebak.o expect.o mkdir.o socket.o targext.o $(EXTRA_LIBGNAT_OBJS)
+LIBGNAT_OBJS = adadecode.o adaint.o argv.o cio.o cstreams.o ctrl_c.o \
+ errno.o exit.o env.o raise.o sysdep.o aux-io.o init.o initialize.o \
+ seh_init.o cal.o arit64.o final.o tracebak.o expect.o mkdir.o \
+ socket.o targext.o $(EXTRA_LIBGNAT_OBJS)
# NOTE ??? - when the -I option for compiling Ada code is made to work,
# the library installation will change and there will be a
@@ -2183,7 +2151,7 @@ ADA_INCLUDE_SRCS =\
LIBGNAT=../$(RTSDIR)/libgnat.a
-GCC_LINK=$(CC) -static-libgcc $(ADA_INCLUDES)
+GCC_LINK=$(CC) $(GCC_LINK_FLAGS) $(ADA_INCLUDES)
# when compiling the tools, the runtime has to be first on the path so that
# it hides the runtime files lying with the rest of the sources
@@ -2400,11 +2368,6 @@ gnatlib: ../stamp-gnatlib1-$(RTSDIR) ../stamp-gnatlib2-$(RTSDIR)
$(RM) $(RTSDIR)/libgnat$(arext) $(RTSDIR)/libgnarl$(arext)
$(AR_FOR_TARGET) $(AR_FLAGS) $(RTSDIR)/libgnat$(arext) \
$(addprefix $(RTSDIR)/,$(GNATRTL_NONTASKING_OBJS) $(LIBGNAT_OBJS))
- ifneq ($(PREFIX_OBJS),)
- $(AR_FOR_TARGET) $(AR_FLAGS) $(RTSDIR)/libgccprefix$(arext) \
- $(PREFIX_OBJS);
- $(RANLIB_FOR_TARGET) $(RTSDIR)/libgccprefix$(arext)
- endif
$(RANLIB_FOR_TARGET) $(RTSDIR)/libgnat$(arext)
$(AR_FOR_TARGET) $(AR_FLAGS) $(RTSDIR)/libgnarl$(arext) \
$(addprefix $(RTSDIR)/,$(GNATRTL_TASKING_OBJS))
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index d14305e42f0..eff96837653 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -5321,6 +5321,7 @@ gnat_to_gnu (Node_Id gnat_node)
case N_SCIL_Dispatch_Table_Object_Init:
case N_SCIL_Dispatch_Table_Tag_Init:
case N_SCIL_Dispatching_Call:
+ case N_SCIL_Membership_Test:
case N_SCIL_Tag_Init:
/* SCIL nodes require no processing for GCC. */
gnu_result = alloc_stmt_list ();
diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb
index ca4fe86c8f6..79824868be5 100644
--- a/gcc/ada/gnat1drv.adb
+++ b/gcc/ada/gnat1drv.adb
@@ -158,10 +158,23 @@ procedure Gnat1drv is
Front_End_Inlining := False;
Inline_Active := False;
- -- Turn off ASIS mode: incompatible with front-end expansion.
+ -- Turn off ASIS mode: incompatible with front-end expansion
ASIS_Mode := False;
+ -- Disable front-end optimizations, to keep the tree as close to the
+ -- source code as possible, and also to avoid inconsistencies between
+ -- trees when using different optimization switches.
+
+ Optimization_Level := 0;
+
+ -- Disable specific expansions for Restrictions pragmas to avoid
+ -- tree inconsistencies between compilations with different pragmas
+ -- that will cause different SCIL files to be generated for the
+ -- same Ada spec.
+
+ Treat_Restrictions_As_Warnings := True;
+
-- Suppress overflow, division by zero and access checks since they
-- are handled implicitly by CodePeer.
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index 4b906fe91e9..46823f9ebad 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -112,6 +112,7 @@ Implementation Defined Pragmas
* Pragma Common_Object::
* Pragma Compile_Time_Error::
* Pragma Compile_Time_Warning::
+* Pragma Compiler_Unit::
* Pragma Complete_Representation::
* Pragma Complex_Representation::
* Pragma Component_Alignment::
@@ -181,6 +182,7 @@ Implementation Defined Pragmas
* Pragma Pure_Function::
* Pragma Restriction_Warnings::
* Pragma Shared::
+* Pragma Short_Circuit_And_Or::
* Pragma Source_File_Name::
* Pragma Source_File_Name_Project::
* Pragma Source_Reference::
@@ -252,6 +254,7 @@ Implementation Defined Attributes
* Passed_By_Reference::
* Pool_Address::
* Range_Length::
+* Result::
* Safe_Emax::
* Safe_Large::
* Small::
@@ -374,6 +377,10 @@ The GNAT Library
* GNAT.Semaphores (g-semaph.ads)::
* GNAT.Serial_Communications (g-sercom.ads)::
* GNAT.SHA1 (g-sha1.ads)::
+* GNAT.SHA224 (g-sha224.ads)::
+* GNAT.SHA256 (g-sha256.ads)::
+* GNAT.SHA384 (g-sha384.ads)::
+* GNAT.SHA512 (g-sha512.ads)::
* GNAT.Signals (g-signal.ads)::
* GNAT.Sockets (g-socket.ads)::
* GNAT.Source_Info (g-souinf.ads)::
@@ -722,6 +729,7 @@ consideration, the use of these pragmas should be minimized.
* Pragma Common_Object::
* Pragma Compile_Time_Error::
* Pragma Compile_Time_Warning::
+* Pragma Compiler_Unit::
* Pragma Complete_Representation::
* Pragma Complex_Representation::
* Pragma Component_Alignment::
@@ -791,6 +799,7 @@ consideration, the use of these pragmas should be minimized.
* Pragma Pure_Function::
* Pragma Restriction_Warnings::
* Pragma Shared::
+* Pragma Short_Circuit_And_Or::
* Pragma Source_File_Name::
* Pragma Source_File_Name_Project::
* Pragma Source_Reference::
@@ -924,7 +933,7 @@ same syntax and effect.
@noindent
Syntax:
@smallexample @c ada
-pragma Annotate (IDENTIFIER @{, ARG@});
+pragma Annotate (IDENTIFIER [,IDENTIFIER] @{, ARG@});
ARG ::= NAME | EXPRESSION
@end smallexample
@@ -932,11 +941,14 @@ ARG ::= NAME | EXPRESSION
@noindent
This pragma is used to annotate programs. @var{identifier} identifies
the type of annotation. GNAT verifies that it is an identifier, but does
-not otherwise analyze it. The @var{arg} argument
-can be either a string literal or an
-expression. String literals are assumed to be of type
-@code{Standard.String}. Names of entities are simply analyzed as entity
-names. All other expressions are analyzed as expressions, and must be
+not otherwise analyze it. The second optional identifier is also left
+unanalyzed, and by convention is used to control the action of the tool to
+which the annotation is addressed. The remaining @var{arg} arguments
+can be either string literals or more generally expressions.
+String literals are assumed to be either of type
+@code{Standard.String} or else @code{Wide_String} or @code{Wide_Wide_String}
+depending on the character literals they contain.
+All other kinds of arguments are analyzed as expressions, and must be
unambiguous.
The analyzed pragma is retained in the tree, but not otherwise processed
@@ -1333,6 +1345,24 @@ of formal parameters are tested, and warnings given appropriately. Another use
with a first parameter of True is to warn a client about use of a package,
for example that it is not fully implemented.
+@node Pragma Compiler_Unit
+@unnumberedsec Pragma Compiler_Unit
+@findex Compiler_Unit
+@noindent
+Syntax:
+
+@smallexample @c ada
+pragma Compiler_Unit;
+@end smallexample
+
+@noindent
+This pragma is intended only for internal use in the GNAT run-time library.
+It indicates that the unit is used as part of the compiler build. The effect
+is to disallow constructs (raise with message, conditional expressions etc)
+that would cause trouble when bootstrapping using an older version of GNAT.
+For the exact list of restrictions, see the compiler sources and references
+to Is_Compiler_Unit.
+
@node Pragma Complete_Representation
@unnumberedsec Pragma Complete_Representation
@findex Complete_Representation
@@ -4233,6 +4263,20 @@ if the restriction is violated.
This pragma is provided for compatibility with Ada 83. The syntax and
semantics are identical to pragma Atomic.
+@node Pragma Short_Circuit_And_Or
+@unnumberedsec Pragma Short_Circuit_And_Or
+@findex Short_Circuit_And_Or
+
+@noindent
+This configuration pragma causes any occurrence of the AND operator applied to
+operands of type Standard.Boolean to be short-circuited (i.e. the AND operator
+is treated as if it were AND THEN). Or is similarly treated as OR ELSE. This
+may be useful in the context of certification protocols requiring the use of
+short-circuited logical operators. If this configuration pragma occurs locally
+within the file being compiled, it applies only to the file being compiled.
+There is no requirement that all units in a partition use this option.
+
+semantics are identical to pragma Atomic.
@node Pragma Source_File_Name
@unnumberedsec Pragma Source_File_Name
@findex Source_File_Name
@@ -5157,80 +5201,12 @@ The form with a single static_string_EXPRESSION argument provides more precise
control over which warnings are active. The string is a list of letters
specifying which warnings are to be activated and which deactivated. The
code for these letters is the same as the string used in the command
-line switch controlling warnings. The following is a brief summary. For
+line switch controlling warnings. For a brief summary, use the gnatmake
+command with no arguments, which will generate usage information containing
+the list of warnings switches supported. For
full details see @ref{Warning Message Control,,, gnat_ugn, @value{EDITION}
User's Guide}.
-@smallexample
-a turn on all optional warnings (except d h l .o)
-A turn off all optional warnings
-.a* turn on warnings for failing assertions
-.A turn off warnings for failing assertions
-b turn on warnings for bad fixed value (not multiple of small)
-B* turn off warnings for bad fixed value (not multiple of small)
-.b* turn on warnings for biased representation
-.B turn off warnings for biased representation
-c turn on warnings for constant conditional
-C* turn off warnings for constant conditional
-.c turn on warnings for unrepped components
-.C* turn off warnings for unrepped components
-d turn on warnings for implicit dereference
-D* turn off warnings for implicit dereference
-e treat all warnings as errors
-.e turn on every optional warning
-f turn on warnings for unreferenced formal
-F* turn off warnings for unreferenced formal
-g* turn on warnings for unrecognized pragma
-G turn off warnings for unrecognized pragma
-h turn on warnings for hiding variable
-H* turn off warnings for hiding variable
-i* turn on warnings for implementation unit
-I turn off warnings for implementation unit
-j turn on warnings for obsolescent (annex J) feature
-J* turn off warnings for obsolescent (annex J) feature
-k turn on warnings on constant variable
-K* turn off warnings on constant variable
-l turn on warnings for missing elaboration pragma
-L* turn off warnings for missing elaboration pragma
-m turn on warnings for variable assigned but not read
-M* turn off warnings for variable assigned but not read
-n* normal warning mode (cancels -gnatws/-gnatwe)
-o* turn on warnings for address clause overlay
-O turn off warnings for address clause overlay
-.o turn on warnings for out parameters assigned but not read
-.O* turn off warnings for out parameters assigned but not read
-p turn on warnings for ineffective pragma Inline in frontend
-P* turn off warnings for ineffective pragma Inline in frontend
-.p turn on warnings for parameter ordering
-.P* turn off warnings for parameter ordering
-q* turn on warnings for questionable missing parentheses
-Q turn off warnings for questionable missing parentheses
-r turn on warnings for redundant construct
-R* turn off warnings for redundant construct
-.r turn on warnings for object renaming function
-.R* turn off warnings for object renaming function
-s suppress all warnings
-t turn on warnings for tracking deleted code
-T* turn off warnings for tracking deleted code
-u turn on warnings for unused entity
-U* turn off warnings for unused entity
-v* turn on warnings for unassigned variable
-V turn off warnings for unassigned variable
-w* turn on warnings for wrong low bound assumption
-W turn off warnings for wrong low bound assumption
-.w turn on warnings for unnecessary Warnings Off pragmas
-.W* turn off warnings for unnecessary Warnings Off pragmas
-x* turn on warnings for export/import
-X turn off warnings for export/import
-.x turn on warnings for non-local exceptions
-.X* turn off warnings for non-local exceptions
-y* turn on warnings for Ada 2005 incompatibility
-Y turn off warnings for Ada 2005 incompatibility
-z* turn on convention/size/align warnings for unchecked conversion
-Z turn off convention/size/align warnings for unchecked conversion
-* indicates default in above list
-@end smallexample
-
@noindent
The specified warnings will be in effect until the end of the program
or another pragma Warnings is encountered. The effect of the pragma is
@@ -5268,6 +5244,11 @@ pragma Warnings (On, Pattern);
In this usage, the pattern string must match in the Off and On pragmas,
and at least one matching warning must be suppressed.
+Note: the debug flag -gnatd.i (@code{/NOWARNINGS_PRAGMAS} in VMS) can be
+used to cause the compiler to entirely ignore all WARNINGS pragmas. This can
+be useful in checking whether obsolete pragmas in existing programs are hiding
+real problems.
+
@node Pragma Weak_External
@unnumberedsec Pragma Weak_External
@findex Weak_External
@@ -5403,6 +5384,7 @@ consideration, you should minimize the use of these attributes.
* Passed_By_Reference::
* Pool_Address::
* Range_Length::
+* Result::
* Safe_Emax::
* Safe_Large::
* Small::
@@ -6054,6 +6036,16 @@ range). The result is static for static subtypes. @code{Range_Length}
applied to the index subtype of a one dimensional array always gives the
same result as @code{Range} applied to the array itself.
+@node Result
+@unnumberedsec Result
+@findex Result
+@noindent
+@code{@var{function}'Result} can only be used with in a Postcondition pragma
+for a function. The prefix must be the name of the corresponding function. This
+is used to refer to the result of the function in the postcondition expression.
+For a further discussion of the use of this attribute and examples of its use,
+see the description of pragma Postcondition.
+
@node Safe_Emax
@unnumberedsec Safe_Emax
@cindex Ada 83 attributes
@@ -13566,6 +13558,10 @@ of GNAT, and will generate a warning message.
* GNAT.Semaphores (g-semaph.ads)::
* GNAT.Serial_Communications (g-sercom.ads)::
* GNAT.SHA1 (g-sha1.ads)::
+* GNAT.SHA224 (g-sha224.ads)::
+* GNAT.SHA256 (g-sha256.ads)::
+* GNAT.SHA384 (g-sha384.ads)::
+* GNAT.SHA512 (g-sha512.ads)::
* GNAT.Signals (g-signal.ads)::
* GNAT.Sockets (g-socket.ads)::
* GNAT.Source_Info (g-souinf.ads)::
@@ -14563,7 +14559,40 @@ port. This is only supported on GNU/Linux and Windows.
@cindex Secure Hash Algorithm SHA-1
@noindent
-Implements the SHA-1 Secure Hash Algorithm as described in RFC 3174.
+Implements the SHA-1 Secure Hash Algorithm as described in FIPS PUB 180-3
+and RFC 3174.
+
+@node GNAT.SHA224 (g-sha224.ads)
+@section @code{GNAT.SHA224} (@file{g-sha224.ads})
+@cindex @code{GNAT.SHA224} (@file{g-sha224.ads})
+@cindex Secure Hash Algorithm SHA-224
+
+@noindent
+Implements the SHA-224 Secure Hash Algorithm as described in FIPS PUB 180-3.
+
+@node GNAT.SHA256 (g-sha256.ads)
+@section @code{GNAT.SHA256} (@file{g-sha256.ads})
+@cindex @code{GNAT.SHA256} (@file{g-sha256.ads})
+@cindex Secure Hash Algorithm SHA-256
+
+@noindent
+Implements the SHA-256 Secure Hash Algorithm as described in FIPS PUB 180-3.
+
+@node GNAT.SHA384 (g-sha384.ads)
+@section @code{GNAT.SHA384} (@file{g-sha384.ads})
+@cindex @code{GNAT.SHA384} (@file{g-sha384.ads})
+@cindex Secure Hash Algorithm SHA-384
+
+@noindent
+Implements the SHA-384 Secure Hash Algorithm as described in FIPS PUB 180-3.
+
+@node GNAT.SHA512 (g-sha512.ads)
+@section @code{GNAT.SHA512} (@file{g-sha512.ads})
+@cindex @code{GNAT.SHA512} (@file{g-sha512.ads})
+@cindex Secure Hash Algorithm SHA-512
+
+@noindent
+Implements the SHA-512 Secure Hash Algorithm as described in FIPS PUB 180-3.
@node GNAT.Signals (g-signal.ads)
@section @code{GNAT.Signals} (@file{g-signal.ads})
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 19304a75f40..78bbf56837f 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -9326,7 +9326,21 @@ This switch cannot be used when using a project file.
@ifclear vms
@item -eL
@cindex @option{-eL} (@command{gnatmake})
+@cindex symbolic links
Follow all symbolic links when processing project files.
+This should be used if your project uses symbolic links for files or
+directories, but is not needed in other cases.
+
+@cindex naming scheme
+This also assumes that no directory matches the naming scheme for files (for
+instance that you do not have a directory called "sources.ads" when using the
+default GNAT naming scheme).
+
+When you do not have to use this switch (ie by default), gnatmake is able to
+save a lot of system calls (several per source file and object file), which
+can result in a significant speed up to load and manipulate a project file,
+especially when using source files from a remote system.
+
@end ifclear
@item ^-eS^/STANDARD_OUTPUT_FOR_COMMANDS^
@@ -20858,28 +20872,29 @@ Turn off the check for a specified rule with the specified parameter, if any.
@cindex @option{-from} (@command{gnatcheck})
@item -from=@var{rule_option_filename}
-Read the rule options from the text file @var{rule_option_filename}, referred as
-``rule file'' below.
+Read the rule options from the text file @var{rule_option_filename}, referred
+to as a ``coding standard file'' below.
@end table
@noindent
The default behavior is that all the rule checks are disabled.
-A rule file is a text file containing a set of rule options.
-@cindex Rule file (for @code{gnatcheck})
+A coding standard file is a text file that contains a set of rule options
+described above.
+@cindex Coding standard file (for @code{gnatcheck})
The file may contain empty lines and Ada-style comments (comment
-lines and end-of-line comments). The rule file has free format; that is,
-you do not have to start a new rule option on a new line.
+lines and end-of-line comments). There can be several rule options on a
+single line (separated by a space).
-A rule file may contain other @option{-from=@var{rule_option_filename}}
+A coding standard file may reference other coding standard files by including
+more @option{-from=@var{rule_option_filename}}
options, each such option being replaced with the content of the
-corresponding rule file during the rule files processing. In case a
+corresponding coding standard file during processing. In case a
cycle is detected (that is, @file{@var{rule_file_1}} reads rule options
from @file{@var{rule_file_2}}, and @file{@var{rule_file_2}} reads
(directly or indirectly) rule options from @file{@var{rule_file_1}}),
-the processing of rule files is interrupted and a part of their content
-is ignored.
+processing fails with an error message.
@node Adding the Results of Compiler Checks to gnatcheck Output
@@ -21013,7 +21028,7 @@ exemption control annotations is as follows:
@group
pragma Annotate (gnatcheck, @i{exemption_control}, @i{Rule_Name}, [@i{justification}]);
-@i{exemption_control} ::= "Exempt_On" | "Exempt_Off"
+@i{exemption_control} ::= Exempt_On | Exempt_Off
@i{Rule_Name} ::= string_literal
@@ -21037,9 +21052,9 @@ A source code section where an exemption is active for a given rule is
delimited by an @code{exempt_on} and @code{exempt_off} annotation pair:
@smallexample @c ada
-pragma Annotate (gnatcheck, "Exempt_On", Rule_Name, "justification");
+pragma Annotate (gnatcheck, Exempt_On, Rule_Name, "justification");
-- source code section
-pragma Annotate (gnatcheck, "Exempt_Off", Rule_Name);
+pragma Annotate (gnatcheck, Exempt_Off, Rule_Name);
@end smallexample
@@ -22519,7 +22534,9 @@ This rule has no parameters.
@cindex @code{Positional_Generic_Parameters} rule (for @command{gnatcheck})
@noindent
-Flag each instantiation using positional parameter notation.
+Flag each positional actual generic parameter except for the case when
+the generic unit being iinstantiated has exactly one generic formal
+parameter.
This rule has no parameters.
@@ -22529,15 +22546,15 @@ This rule has no parameters.
@cindex @code{Positional_Parameters} rule (for @command{gnatcheck})
@noindent
-Flag each subprogram or entry call using positional parameter notation,
+Flag each positional parameter notation in a subprogram or entry call,
except for the following:
@itemize @bullet
@item
-Invocations of prefix or infix operators are not flagged
+Parameters of calls to of prefix or infix operators are not flagged
@item
If the called subprogram or entry has only one formal parameter,
-the call is not flagged;
+the parameter of the call is not flagged;
@item
If a subprogram call uses the @emph{Object.Operation} notation, then
@itemize @minus
diff --git a/gcc/ada/gnatcmd.adb b/gcc/ada/gnatcmd.adb
index e0ccc228473..bfde10d6ae1 100644
--- a/gcc/ada/gnatcmd.adb
+++ b/gcc/ada/gnatcmd.adb
@@ -318,8 +318,31 @@ procedure GNATCmd is
for Index in 1 .. Last_Switches.Last loop
if Last_Switches.Table (Index) (1) /= '-' then
- Add_Sources := False;
- exit;
+ if Index = 1
+ or else
+ (The_Command = Check
+ and then
+ Last_Switches.Table (Index - 1).all /= "-o")
+ or else
+ (The_Command = Pretty
+ and then
+ Last_Switches.Table (Index - 1).all /= "-o" and then
+ Last_Switches.Table (Index - 1).all /= "-of")
+ or else
+ (The_Command = Metric
+ and then
+ Last_Switches.Table (Index - 1).all /= "-o" and then
+ Last_Switches.Table (Index - 1).all /= "-og" and then
+ Last_Switches.Table (Index - 1).all /= "-ox" and then
+ Last_Switches.Table (Index - 1).all /= "-d")
+ or else
+ (The_Command /= Check and then
+ The_Command /= Pretty and then
+ The_Command /= Metric)
+ then
+ Add_Sources := False;
+ exit;
+ end if;
end if;
end loop;
@@ -552,8 +575,12 @@ procedure GNATCmd is
(Unit.File_Names (Kind).Project, Project)
and then not Unit.File_Names (Kind).Locally_Removed
then
- Get_Name_String
- (Unit.File_Names (Kind).Path.Display_Name);
+ Name_Len := 0;
+ Add_Char_To_Name_Buffer ('"');
+ Add_Str_To_Name_Buffer
+ (Get_Name_String
+ (Unit.File_Names (Kind).Path.Display_Name));
+ Add_Char_To_Name_Buffer ('"');
if FD /= Invalid_FD then
Name_Len := Name_Len + 1;
diff --git a/gcc/ada/gnatlink.adb b/gcc/ada/gnatlink.adb
index 5347269be00..708e1794d04 100644
--- a/gcc/ada/gnatlink.adb
+++ b/gcc/ada/gnatlink.adb
@@ -439,34 +439,16 @@ procedure Gnatlink is
Compile_Bind_File := False;
when 'o' =>
- if VM_Target = CLI_Target then
- Linker_Options.Increment_Last;
- Linker_Options.Table (Linker_Options.Last) :=
- new String'("/QUIET");
-
- else
- Linker_Options.Increment_Last;
- Linker_Options.Table (Linker_Options.Last) :=
- new String'(Arg);
- end if;
-
Next_Arg := Next_Arg + 1;
if Next_Arg > Argument_Count then
Exit_With_Error ("Missing argument for -o");
end if;
- if VM_Target = CLI_Target then
- Output_File_Name :=
- new String'("/OUTPUT=" & Argument (Next_Arg));
- else
- Output_File_Name :=
- new String'(Argument (Next_Arg));
- end if;
-
- Linker_Options.Increment_Last;
- Linker_Options.Table (Linker_Options.Last) :=
- Output_File_Name;
+ Output_File_Name :=
+ new String'(Executable_Name
+ (Argument (Next_Arg),
+ Only_If_No_Suffix => True));
when 'R' =>
Opt.Run_Path_Option := False;
@@ -1728,33 +1710,44 @@ begin
Output_File_Name :=
new String'(Base_Name (Ali_File_Name.all)
& Get_Target_Debuggable_Suffix.all);
+ end if;
- if VM_Target = CLI_Target then
- Linker_Options.Increment_Last;
- Linker_Options.Table (Linker_Options.Last) := new String'("/QUIET");
+ if VM_Target = CLI_Target then
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) := new String'("/QUIET");
- Linker_Options.Increment_Last;
- Linker_Options.Table (Linker_Options.Last) := new String'("/DEBUG");
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) := new String'("/DEBUG");
- Linker_Options.Increment_Last;
- Linker_Options.Table (Linker_Options.Last) :=
- new String'("/OUTPUT=" & Output_File_Name.all);
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) :=
+ new String'("/OUTPUT=" & Output_File_Name.all);
- elsif RTX_RTSS_Kernel_Module_On_Target then
- Linker_Options.Increment_Last;
- Linker_Options.Table (Linker_Options.Last) :=
- new String'("/OUT:" & Output_File_Name.all);
+ elsif RTX_RTSS_Kernel_Module_On_Target then
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) :=
+ new String'("/OUT:" & Output_File_Name.all);
- else
- Linker_Options.Increment_Last;
- Linker_Options.Table (Linker_Options.Last) := new String'("-o");
+ else
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) := new String'("-o");
- Linker_Options.Increment_Last;
- Linker_Options.Table (Linker_Options.Last) :=
- new String'(Output_File_Name.all);
- end if;
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) :=
+ new String'(Output_File_Name.all);
end if;
+ -- Delete existing executable, in case it is a symbolic link, to avoid
+ -- modifying the target of the symbolic link.
+
+ declare
+ Dummy : Boolean;
+ pragma Unreferenced (Dummy);
+
+ begin
+ Delete_File (Output_File_Name.all, Dummy);
+ end;
+
-- Warn if main program is called "test", as that may be a built-in command
-- on Unix. On non-Unix systems executables have a suffix, so the warning
-- will not appear. However, do not warn in the case of a cross compiler.
@@ -2148,11 +2141,10 @@ begin
if Linker_Path = Gcc_Path and then VM_Target = No_VM then
- -- For systems where the default is to link statically
- -- with libgcc, if gcc is not called with
- -- -shared-libgcc, call it with -static-libgcc, as
- -- there are some platforms where one of these two
- -- switches is compulsory to link.
+ -- For systems where the default is to link statically with
+ -- libgcc, if gcc is not called with -shared-libgcc, call it
+ -- with -static-libgcc, as there are some platforms where one
+ -- of these two switches is compulsory to link.
if Shared_Libgcc_Default = 'T'
and then not Shared_Libgcc_Seen
diff --git a/gcc/ada/gnatls.adb b/gcc/ada/gnatls.adb
index 5b433187adb..b5a3f49df16 100644
--- a/gcc/ada/gnatls.adb
+++ b/gcc/ada/gnatls.adb
@@ -40,7 +40,6 @@ with Rident; use Rident;
with Sdefault;
with Snames;
with Switch; use Switch;
-with Targparm; use Targparm;
with Types; use Types;
with GNAT.Case_Util; use GNAT.Case_Util;
@@ -1574,8 +1573,6 @@ begin
Osint.Add_Default_Search_Dirs;
if Verbose_Mode then
- Targparm.Get_Target_Parameters;
-
Write_Eol;
Display_Version ("GNATLS", "1997");
Write_Eol;
diff --git a/gcc/ada/i-vxwoio.adb b/gcc/ada/i-vxwoio.adb
index 00ee6356872..4d480e0519f 100644
--- a/gcc/ada/i-vxwoio.adb
+++ b/gcc/ada/i-vxwoio.adb
@@ -63,16 +63,10 @@ package body Interfaces.VxWorks.IO is
is
Status : int;
Fd : int;
-
begin
Fd := fileno (File);
Status := ioctl (Fd, FIOSETOPTIONS, OPT_TERMINAL);
-
- if Status /= int (ERROR) then
- Success := True;
- else
- Success := False;
- end if;
+ Success := (if Status /= int (ERROR) then True else False);
end Disable_Get_Immediate;
end Interfaces.VxWorks.IO;
diff --git a/gcc/ada/impunit.adb b/gcc/ada/impunit.adb
index 4264a5a9db7..0f3ad5793ec 100644
--- a/gcc/ada/impunit.adb
+++ b/gcc/ada/impunit.adb
@@ -263,6 +263,10 @@ package body Impunit is
"g-sercom", -- GNAT.Serial_Communications
"g-sestin", -- GNAT.Secondary_Stack_Info
"g-sha1 ", -- GNAT.SHA1
+ "g-sha224", -- GNAT.SHA224
+ "g-sha256", -- GNAT.SHA256
+ "g-sha384", -- GNAT.SHA384
+ "g-sha512", -- GNAT.SHA512
"g-signal", -- GNAT.Signals
"g-socket", -- GNAT.Sockets
"g-souinf", -- GNAT.Source_Info
diff --git a/gcc/ada/init.c b/gcc/ada/init.c
index a8be23dbb5f..5e5d1c60b44 100644
--- a/gcc/ada/init.c
+++ b/gcc/ada/init.c
@@ -601,14 +601,14 @@ __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
time this happens. */
#if defined (i386)
- unsigned long pattern = *(unsigned long *)mcontext->gregs[REG_EIP];
+ unsigned long *pc = (unsigned long *)mcontext->gregs[REG_EIP];
/* The pattern is "orl $0x0,(%esp)" for a probe in 32-bit mode. */
- if (signo == SIGSEGV && pattern == 0x00240c83)
+ if (signo == SIGSEGV && pc && *pc == 0x00240c83)
mcontext->gregs[REG_ESP] += 4096 + 4 * sizeof (unsigned long);
#elif defined (__x86_64__)
- unsigned long pattern = *(unsigned long *)mcontext->gregs[REG_RIP];
+ unsigned long *pc = (unsigned long *)mcontext->gregs[REG_RIP];
/* The pattern is "orq $0x0,(%rsp)" for a probe in 64-bit mode. */
- if (signo == SIGSEGV && (pattern & 0xffffffffff) == 0x00240c8348)
+ if (signo == SIGSEGV && pc && (*pc & 0xffffffffff) == 0x00240c8348)
mcontext->gregs[REG_RSP] += 4096 + 4 * sizeof (unsigned long);
#elif defined (__ia64__)
/* ??? The IA-64 unwinder doesn't compensate for signals. */
diff --git a/gcc/ada/lib-writ.ads b/gcc/ada/lib-writ.ads
index d5236773a3d..fa8af04d6ae 100644
--- a/gcc/ada/lib-writ.ads
+++ b/gcc/ada/lib-writ.ads
@@ -157,7 +157,7 @@ package Lib.Writ is
-- One of these lines appears for each of the arguments present in the
-- call to the gnat1 program. This can be used if it is necessary to
- -- reconstruct this call (e.g. for fix and continue)
+ -- reconstruct this call (e.g. for fix and continue).
-- -------------------
-- -- P Parameters --
@@ -235,7 +235,7 @@ package Lib.Writ is
-- generated exception tables. If ZX is not present, the
-- longjmp/setjmp exception scheme is in use.
--
- -- Note that language defined units never output policy (Lx,Tx,Qx)
+ -- Note that language defined units never output policy (Lx, Tx, Qx)
-- parameters. Language defined units must correctly handle all
-- possible cases. These values are checked for consistency by the
-- binder and then copied to the generated binder output file.
diff --git a/gcc/ada/make.adb b/gcc/ada/make.adb
index 12e6386d045..0e3c85765d5 100644
--- a/gcc/ada/make.adb
+++ b/gcc/ada/make.adb
@@ -2453,14 +2453,12 @@ package body Make is
procedure Await_Compile
(Data : out Compilation_Data;
OK : out Boolean);
- -- Awaits that an outstanding compilation process terminates. When
- -- it does set Data to the information registered for the corresponding
- -- call to Add_Process.
- -- Note that this time stamp can be used to check whether the
- -- compilation did generate an object file. OK is set to True if the
- -- compilation succeeded.
- -- Data could be No_Compilation_Data if there was no compilation to wait
- -- for.
+ -- Awaits that an outstanding compilation process terminates. When it
+ -- does set Data to the information registered for the corresponding
+ -- call to Add_Process. Note that this time stamp can be used to check
+ -- whether the compilation did generate an object file. OK is set to
+ -- True if the compilation succeeded. Data could be No_Compilation_Data
+ -- if there was no compilation to wait for.
function Bad_Compilation_Count return Natural;
-- Returns the number of compilation failures
@@ -2474,9 +2472,9 @@ package body Make is
Source_Index : Int;
Pid : out Process_Id;
Process_Created : out Boolean);
- -- Collect arguments from project file (if any) and compile.
- -- If no compilation was attempted, Processed_Created is set to False,
- -- and the value of Pid is unknown.
+ -- Collect arguments from project file (if any) and compile. If no
+ -- compilation was attempted, Processed_Created is set to False, and the
+ -- value of Pid is unknown.
function Compile
(Project : Project_Id;
@@ -2579,18 +2577,18 @@ package body Make is
-------------------
procedure Await_Compile
- (Data : out Compilation_Data;
- OK : out Boolean)
+ (Data : out Compilation_Data;
+ OK : out Boolean)
is
- Pid : Process_Id;
- Project : Project_Id;
+ Pid : Process_Id;
+ Project : Project_Id;
Comp_Data : Project_Compilation_Access;
begin
pragma Assert (Outstanding_Compiles > 0);
- Data := No_Compilation_Data;
- OK := False;
+ Data := No_Compilation_Data;
+ OK := False;
-- The loop here is a work-around for a problem on VMS; in some
-- circumstances (shared library and several executables, for
@@ -2614,13 +2612,14 @@ package body Make is
-- file name for reuse by a subsequent compilation.
if Running_Compile (J).Mapping_File /= No_Mapping_File then
- Comp_Data := Project_Compilation_Htable.Get
- (Project_Compilation, Project);
+ Comp_Data :=
+ Project_Compilation_Htable.Get
+ (Project_Compilation, Project);
Comp_Data.Last_Free_Indices :=
Comp_Data.Last_Free_Indices + 1;
Comp_Data.Free_Mapping_File_Indices
(Comp_Data.Last_Free_Indices) :=
- Running_Compile (J).Mapping_File;
+ Running_Compile (J).Mapping_File;
end if;
-- To actually remove this Pid and related info from
@@ -2629,7 +2628,6 @@ package body Make is
if J = Outstanding_Compiles then
null;
-
else
Running_Compile (J) :=
Running_Compile (Outstanding_Compiles);
@@ -2643,6 +2641,8 @@ package body Make is
-- This child process was not one of our compilation processes;
-- just ignore it for now.
+ -- Why is this commented out code sitting here???
+
-- raise Program_Error;
end loop;
end Await_Compile;
@@ -2678,8 +2678,7 @@ package body Make is
-- library only if we can find it.
if RTS_Switch then
- Add_It :=
- Find_File (Sfile, Osint.Source) /= No_File;
+ Add_It := Full_Source_Name (Sfile) /= No_File;
end if;
if Add_It then
@@ -3001,6 +3000,7 @@ package body Make is
Uname : Unit_Name_Type;
Unit_Name : Name_Id;
Uid : Prj.Unit_Index;
+
begin
while Good_ALI_Present loop
ALI := Get_Next_Good_ALI;
@@ -3015,24 +3015,23 @@ package body Make is
Main_Unit := ALIs.Table (ALI).Main_Program /= None;
end if;
- -- The following adds the standard library (s-stalib) to the
- -- list of files to be handled by gnatmake: this file and any
- -- files it depends on are always included in every bind,
- -- even if they are not in the explicit dependency list.
- -- Of course, it is not added if Suppress_Standard_Library
- -- is True.
+ -- The following adds the standard library (s-stalib) to the list
+ -- of files to be handled by gnatmake: this file and any files it
+ -- depends on are always included in every bind, even if they are
+ -- not in the explicit dependency list. Of course, it is not added
+ -- if Suppress_Standard_Library is True.
- -- However, to avoid annoying output about s-stalib.ali being
- -- read only, when "-v" is used, we add the standard library
- -- only when "-a" is used.
+ -- However, to avoid annoying output about s-stalib.ali being read
+ -- only, when "-v" is used, we add the standard library only when
+ -- "-a" is used.
if Need_To_Check_Standard_Library then
Check_Standard_Library;
end if;
- -- Now insert in the Q the unmarked source files (i.e. those
- -- which have never been inserted in the Q and hence never
- -- considered). Only do that if Unique_Compile is False.
+ -- Now insert in the Q the unmarked source files (i.e. those which
+ -- have never been inserted in the Q and hence never considered).
+ -- Only do that if Unique_Compile is False.
if not Unique_Compile then
for J in
@@ -3044,9 +3043,8 @@ package body Make is
Sfile := Withs.Table (K).Sfile;
Uname := Withs.Table (K).Uname;
- -- If project files are used, find the proper source
- -- to compile, in case Sfile is the spec, but there
- -- is a body.
+ -- If project files are used, find the proper source to
+ -- compile in case Sfile is the spec but there is a body.
if Main_Project /= No_Project then
Get_Name_String (Uname);
@@ -3163,8 +3161,9 @@ package body Make is
--------------------------------
function Must_Exit_Because_Of_Error return Boolean is
- Data : Compilation_Data;
- Success : Boolean;
+ Data : Compilation_Data;
+ Success : Boolean;
+
begin
if Bad_Compilation_Count > 0 and then not Keep_Going then
while Outstanding_Compiles > 0 loop
@@ -3212,29 +3211,29 @@ package body Make is
function Start_Compile_If_Possible
(Args : Argument_List) return Boolean
is
- In_Lib_Dir : Boolean;
- Need_To_Compile : Boolean;
- Pid : Process_Id;
- Process_Created : Boolean;
+ In_Lib_Dir : Boolean;
+ Need_To_Compile : Boolean;
+ Pid : Process_Id;
+ Process_Created : Boolean;
Source_File : File_Name_Type;
Full_Source_File : File_Name_Type;
Source_File_Attr : aliased File_Attributes;
-- The full name of the source file and its attributes (size, ...)
- Source_Unit : Unit_Name_Type;
- Source_Index : Int;
+ Source_Unit : Unit_Name_Type;
+ Source_Index : Int;
-- Index of the current unit in the current source file
- Lib_File : File_Name_Type;
- Full_Lib_File : File_Name_Type;
- Lib_File_Attr : aliased File_Attributes;
- Read_Only : Boolean := False;
- ALI : ALI_Id;
+ Lib_File : File_Name_Type;
+ Full_Lib_File : File_Name_Type;
+ Lib_File_Attr : aliased File_Attributes;
+ Read_Only : Boolean := False;
+ ALI : ALI_Id;
-- The ALI file and its attributes (size, stamp, ...)
- Obj_File : File_Name_Type;
- Obj_Stamp : Time_Stamp_Type;
+ Obj_File : File_Name_Type;
+ Obj_Stamp : Time_Stamp_Type;
-- The object file
begin
@@ -3247,13 +3246,19 @@ package body Make is
Attr => Source_File_Attr'Access);
Lib_File := Osint.Lib_File_Name (Source_File, Source_Index);
+
+ -- ??? This call could be avoided when using projects, since we
+ -- know where the ALI file is supposed to be. That would avoid
+ -- searches in the object directories, including in the runtime
+ -- dir. However, that would require getting access to the
+ -- Source_Id.
+
Osint.Full_Lib_File_Name
(Lib_File,
Lib_File => Full_Lib_File,
Attr => Lib_File_Attr);
- -- If this source has already been compiled, the executable is
- -- obsolete.
+ -- If source has already been compiled, executable is obsolete
if Is_In_Obsoleted (Source_File) then
Executable_Obsolete := True;
@@ -3359,7 +3364,8 @@ package body Make is
end if;
if not Need_To_Compile then
- -- The ALI file is up-to-date. Record its Id
+
+ -- The ALI file is up-to-date; record its Id
Record_Good_ALI (ALI);
@@ -3368,15 +3374,15 @@ package body Make is
if First_Compiled_File = No_File
and then (Most_Recent_Obj_File = No_File
- or else Obj_Stamp > Most_Recent_Obj_Stamp)
+ or else Obj_Stamp > Most_Recent_Obj_Stamp)
then
Most_Recent_Obj_File := Obj_File;
Most_Recent_Obj_Stamp := Obj_Stamp;
end if;
else
- -- Check that switch -x has been used if a source
- -- outside of project files need to be compiled.
+ -- Check that switch -x has been used if a source outside
+ -- of project files need to be compiled.
if Main_Project /= No_Project
and then Arguments_Project = No_Project
@@ -3396,6 +3402,7 @@ package body Make is
Most_Recent_Obj_File := No_File;
if Do_Not_Execute then
+
-- Exit the main loop
return True;
@@ -3404,15 +3411,17 @@ package body Make is
-- Compute where the ALI file must be generated in
-- In_Place_Mode (this does not require to know the
- -- location of the object directory)
+ -- location of the object directory).
if In_Place_Mode then
if Full_Lib_File = No_File then
+
-- If the library file was not found, then save
-- the library file near the source file.
- Lib_File := Osint.Lib_File_Name
- (Full_Source_File, Source_Index);
+ Lib_File :=
+ Osint.Lib_File_Name
+ (Full_Source_File, Source_Index);
Full_Lib_File := Lib_File;
else
@@ -3423,9 +3432,9 @@ package body Make is
end if;
end if;
- -- Start the compilation and record it. We can do
- -- this because there is at least one free process.
- -- This might change the current directory
+ -- Start the compilation and record it. We can do this
+ -- because there is at least one free process. This might
+ -- change the current directory.
Collect_Arguments_And_Compile
(Full_Source_File => Full_Source_File,
@@ -3441,6 +3450,7 @@ package body Make is
-- being the same to find the resulting ALI file.
if not In_Place_Mode then
+
-- Compute the expected location of the ALI file. This
-- can be from several places:
-- -i => in place mode. In such a case,
@@ -3456,6 +3466,7 @@ package body Make is
Add_Str_To_Name_Buffer (Object_Directory_Path.all);
Add_Str_To_Name_Buffer (Get_Name_String (Lib_File));
Full_Lib_File := Name_Find;
+
else
if Project_Of_Current_Object_Directory /=
No_Project
@@ -3466,6 +3477,7 @@ package body Make is
Add_Str_To_Name_Buffer
(Get_Name_String (Lib_File));
Full_Lib_File := Name_Find;
+
else
Full_Lib_File := Lib_File;
end if;
@@ -3475,21 +3487,20 @@ package body Make is
Lib_File_Attr := Unknown_Attributes;
- -- Make sure we could successfully start
- -- the Compilation.
+ -- Make sure we could successfully start the compilation
if Process_Created then
if Pid = Invalid_Pid then
Record_Failure (Full_Source_File, Source_Unit);
else
Add_Process
- (Pid => Pid,
- Sfile => Full_Source_File,
- Afile => Lib_File,
- Uname => Source_Unit,
- Mfile => Mfile,
- Full_Lib_File => Full_Lib_File,
- Lib_File_Attr => Lib_File_Attr);
+ (Pid => Pid,
+ Sfile => Full_Source_File,
+ Afile => Lib_File,
+ Uname => Source_Unit,
+ Mfile => Mfile,
+ Full_Lib_File => Full_Lib_File,
+ Lib_File_Attr => Lib_File_Attr);
end if;
end if;
end if;
@@ -3504,16 +3515,16 @@ package body Make is
-----------------------------
procedure Wait_For_Available_Slot is
- Compilation_OK : Boolean;
- Text : Text_Buffer_Ptr;
- ALI : ALI_Id;
- Data : Compilation_Data;
+ Compilation_OK : Boolean;
+ Text : Text_Buffer_Ptr;
+ ALI : ALI_Id;
+ Data : Compilation_Data;
begin
if Outstanding_Compiles = Max_Process
or else (Empty_Q
- and then not Good_ALI_Present
- and then Outstanding_Compiles > 0)
+ and then not Good_ALI_Present
+ and then Outstanding_Compiles > 0)
then
Await_Compile (Data, Compilation_OK);
@@ -3536,26 +3547,28 @@ package body Make is
Check_Object_Consistency :=
Check_Object_Consistency
- and Compilation_OK
- and (Output_Is_Object or Do_Bind_Step);
+ and Compilation_OK
+ and (Output_Is_Object or Do_Bind_Step);
- Text := Read_Library_Info_From_Full
- (Data.Full_Lib_File, Data.Lib_File_Attr'Access);
+ Text :=
+ Read_Library_Info_From_Full
+ (Data.Full_Lib_File, Data.Lib_File_Attr'Access);
-- Restore Check_Object_Consistency to its initial value
Check_Object_Consistency := Saved_Object_Consistency;
end;
- -- If an ALI file was generated by this compilation, scan
- -- the ALI file and record it.
+ -- If an ALI file was generated by this compilation, scan the
+ -- ALI file and record it.
-- If the scan fails, a previous ali file is inconsistent with
-- the unit just compiled.
if Text /= null then
- ALI := Scan_ALI
- (Data.Lib_File, Text, Ignore_ED => False, Err => True);
+ ALI :=
+ Scan_ALI
+ (Data.Lib_File, Text, Ignore_ED => False, Err => True);
if ALI = No_ALI_Id then
@@ -3616,11 +3629,11 @@ package body Make is
end if;
-- The following two flags affect the behavior of ALI.Set_Source_Table.
- -- We set Check_Source_Files to True to ensure that source file
- -- time stamps are checked, and we set All_Sources to False to
- -- avoid checking the presence of the source files listed in the
- -- source dependency section of an ali file (which would be a mistake
- -- since the ali file may be obsolete).
+ -- We set Check_Source_Files to True to ensure that source file time
+ -- stamps are checked, and we set All_Sources to False to avoid checking
+ -- the presence of the source files listed in the source dependency
+ -- section of an ali file (which would be a mistake since the ali file
+ -- may be obsolete).
Check_Source_Files := True;
All_Sources := False;
@@ -4357,8 +4370,7 @@ package body Make is
-- Otherwise, if there is a spec, put it in the mapping
elsif Unit.File_Names (Spec) /= No_Source
- and then Unit.File_Names (Spec).Project /=
- No_Project
+ and then Unit.File_Names (Spec).Project /= No_Project
then
Get_Name_String (Unit.Name);
Add_Str_To_Name_Buffer ("%s");
@@ -4576,9 +4588,9 @@ package body Make is
end if;
-- If no mains have been specified on the command line, and we are
- -- using a project file, we either find the main(s) in attribute
- -- Main of the main project, or we put all the sources of the project
- -- file as mains.
+ -- using a project file, we either find the main(s) in attribute Main
+ -- of the main project, or we put all the sources of the project file
+ -- as mains.
else
if Main_Index /= 0 then
@@ -4626,19 +4638,18 @@ package body Make is
end if;
else
- -- The attribute Main is not an empty list.
- -- Put all the main subprograms in the list as if they were
- -- specified on the command line. However, if attribute
- -- Languages includes a language other than Ada, only
- -- include the Ada mains; if there is no Ada main, compile
- -- all the sources of the project.
+ -- The attribute Main is not an empty list. Put all the main
+ -- subprograms in the list as if they were specified on the
+ -- command line. However, if attribute Languages includes a
+ -- language other than Ada, only include the Ada mains; if
+ -- there is no Ada main, compile all sources of the project.
declare
Languages : constant Variable_Value :=
Prj.Util.Value_Of
- (Name_Languages,
- Main_Project.Decl.Attributes,
- Project_Tree);
+ (Name_Languages,
+ Main_Project.Decl.Attributes,
+ Project_Tree);
Current : String_List_Id;
Element : String_Element;
@@ -4652,7 +4663,6 @@ package body Make is
if not Languages.Default then
Current := Languages.Values;
-
Look_For_Foreign :
while Current /= Nil_String loop
Element := Project_Tree.String_Elements.
@@ -6871,24 +6881,15 @@ package body Make is
-- We add the source directories and the object directories to the
-- search paths.
+ -- ??? Why do we need these search directories, we already know the
+ -- locations from parsing the project, except for the runtime which
+ -- has its own directories anyway
Add_Source_Directories (Main_Project, Project_Tree);
Add_Object_Directories (Main_Project);
Recursive_Compute_Depth (Main_Project);
-
- -- For each project compute the list of the projects it imports
- -- directly or indirectly.
-
- declare
- Proj : Project_List;
- begin
- Proj := Project_Tree.Projects;
- while Proj /= null loop
- Compute_All_Imported_Projects (Proj.Project);
- Proj := Proj.Next;
- end loop;
- end;
+ Compute_All_Imported_Projects (Project_Tree);
else
@@ -7698,6 +7699,7 @@ package body Make is
declare
Norm : constant String := Normalize_Pathname (Argv);
+
begin
if Norm (Norm'Last) = Directory_Separator then
Object_Directory_Path := new String'(Norm);
diff --git a/gcc/ada/makeutl.adb b/gcc/ada/makeutl.adb
index 307ec6ffccc..ab00b506578 100644
--- a/gcc/ada/makeutl.adb
+++ b/gcc/ada/makeutl.adb
@@ -157,6 +157,47 @@ package body Makeutl is
end if;
end Add_Linker_Option;
+ -------------------------
+ -- Base_Name_Index_For --
+ -------------------------
+
+ function Base_Name_Index_For
+ (Main : String;
+ Main_Index : Int;
+ Index_Separator : Character) return File_Name_Type
+ is
+ Result : File_Name_Type;
+
+ begin
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer (Base_Name (Main));
+
+ -- Remove the extension, if any, that is the last part of the base name
+ -- starting with a dot and following some characters.
+
+ for J in reverse 2 .. Name_Len loop
+ if Name_Buffer (J) = '.' then
+ Name_Len := J - 1;
+ exit;
+ end if;
+ end loop;
+
+ -- Add the index info, if index is different from 0
+
+ if Main_Index > 0 then
+ Add_Char_To_Name_Buffer (Index_Separator);
+
+ declare
+ Img : constant String := Main_Index'Img;
+ begin
+ Add_Str_To_Name_Buffer (Img (2 .. Img'Last));
+ end;
+ end if;
+
+ Result := Name_Find;
+ return Result;
+ end Base_Name_Index_For;
+
------------------------------
-- Check_Source_Info_In_ALI --
------------------------------
@@ -231,7 +272,7 @@ package body Makeutl is
if not Fname.Is_Internal_File_Name (SD.Sfile)
or else
(Check_Readonly_Files
- and then Find_File (SD.Sfile, Osint.Source) = No_File)
+ and then Full_Source_Name (SD.Sfile) = No_File)
then
if Verbose_Mode then
Write_Line
@@ -329,8 +370,8 @@ package body Makeutl is
end if;
return Normalize_Pathname
- (Exec (Exec'First .. Path_Last - 4),
- Resolve_Links => Opt.Follow_Links_For_Dirs)
+ (Exec (Exec'First .. Path_Last - 4),
+ Resolve_Links => Opt.Follow_Links_For_Dirs)
& Directory_Separator;
end Get_Install_Dir;
@@ -599,6 +640,7 @@ package body Makeutl is
type File_And_Loc is record
File_Name : File_Name_Type;
+ Index : Int := 0;
Location : Source_Ptr := No_Location;
end record;
@@ -623,7 +665,7 @@ package body Makeutl is
Name_Len := 0;
Add_Str_To_Name_Buffer (Name);
Names.Increment_Last;
- Names.Table (Names.Last) := (Name_Find, No_Location);
+ Names.Table (Names.Last) := (Name_Find, 0, No_Location);
end Add_Main;
------------
@@ -636,6 +678,19 @@ package body Makeutl is
Mains.Reset;
end Delete;
+ ---------------
+ -- Get_Index --
+ ---------------
+
+ function Get_Index return Int is
+ begin
+ if Current in Names.First .. Names.Last then
+ return Names.Table (Current).Index;
+ else
+ return 0;
+ end if;
+ end Get_Index;
+
------------------
-- Get_Location --
------------------
@@ -681,6 +736,17 @@ package body Makeutl is
Current := 0;
end Reset;
+ ---------------
+ -- Set_Index --
+ ---------------
+
+ procedure Set_Index (Index : Int) is
+ begin
+ if Names.Last > 0 then
+ Names.Table (Names.Last).Index := Index;
+ end if;
+ end Set_Index;
+
------------------
-- Set_Location --
------------------
diff --git a/gcc/ada/makeutl.ads b/gcc/ada/makeutl.ads
index 95114f07c9a..a7614f399c4 100644
--- a/gcc/ada/makeutl.ads
+++ b/gcc/ada/makeutl.ads
@@ -60,7 +60,14 @@ package Makeutl is
function Create_Name (Name : String) return File_Name_Type;
function Create_Name (Name : String) return Name_Id;
function Create_Name (Name : String) return Path_Name_Type;
- -- Get the Name_Id of a name
+ -- Get an id for a name
+
+ function Base_Name_Index_For
+ (Main : String;
+ Main_Index : Int;
+ Index_Separator : Character) return File_Name_Type;
+ -- Returns the base name of Main, without the extension, followed by the
+ -- Index_Separator followed by the Main_Index if it is non-zero.
function Executable_Prefix_Path return String;
-- Return the absolute path parent directory of the directory where the
@@ -80,9 +87,9 @@ package Makeutl is
-- one of its source. Returns False otherwise.
function Check_Source_Info_In_ALI (The_ALI : ALI.ALI_Id) return Boolean;
- -- Check whether all file references in ALI are still valid (ie the
+ -- Check whether all file references in ALI are still valid (i.e. the
-- source files are still associated with the same units). Return True
- -- if everything is still valid
+ -- if everything is still valid.
function Is_External_Assignment
(Tree : Prj.Tree.Project_Node_Tree_Ref;
@@ -114,11 +121,11 @@ package Makeutl is
S2 : String := "";
Prefix : String := " -> ";
Minimum_Verbosity : Opt.Verbosity_Level_Type := Opt.Low);
- -- If the verbose flag (Verbose_Mode) is set and the verbosity level is
- -- at least equal to Minimum_Verbosity, then print Prefix to standard
- -- output followed by N1 and S1. If N2 /= No_Name then N2 is printed after
- -- S1. S2 is printed last. Both N1 and N2 are printed in quotation marks.
- -- The two forms differ only in taking Name_Id or File_name_Type arguments.
+ -- If the verbose flag (Verbose_Mode) is set and the verbosity level is at
+ -- least equal to Minimum_Verbosity, then print Prefix to standard output
+ -- followed by N1 and S1. If N2 /= No_Name then N2 is printed after S1. S2
+ -- is printed last. Both N1 and N2 are printed in quotation marks. The two
+ -- forms differ only in taking Name_Id or File_name_Type arguments.
function Linker_Options_Switches
(Project : Project_Id;
@@ -135,14 +142,36 @@ package Makeutl is
-- Find the index of a unit in a source file. Return zero if the file is
-- not a multi-unit source file.
- package Mains is
+ procedure Test_If_Relative_Path
+ (Switch : in out String_Access;
+ Parent : String;
+ Including_L_Switch : Boolean := True;
+ Including_Non_Switch : Boolean := True;
+ Including_RTS : Boolean := False);
+ -- Test if Switch is a relative search path switch. If it is, fail if
+ -- Parent is the empty string, otherwise prepend the path with Parent.
+ -- This subprogram is only called when using project files. For gnatbind
+ -- switches, Including_L_Switch is False, because the argument of the -L
+ -- switch is not a path. If Including_RTS is True, process also switches
+ -- --RTS=.
+
+ function Path_Or_File_Name (Path : Path_Name_Type) return String;
+ -- Returns a file name if -df is used, otherwise return a path name
+
+ -----------
+ -- Mains --
+ -----------
+
+ -- Mains are stored in a table. An index is used to retrieve the mains
+ -- from the table.
- -- Mains are stored in a table. An index is used to retrieve the mains
- -- from the table.
+ package Mains is
procedure Add_Main (Name : String);
-- Add one main to the table
+ procedure Set_Index (Index : Int);
+
procedure Set_Location (Location : Source_Ptr);
-- Set the location of the last main added. By default, the location is
-- No_Location.
@@ -157,6 +186,8 @@ package Makeutl is
-- Increase the index and return the next main. If table is exhausted,
-- return an empty string.
+ function Get_Index return Int;
+
function Get_Location return Source_Ptr;
-- Get the location of the current main
@@ -169,22 +200,6 @@ package Makeutl is
end Mains;
- procedure Test_If_Relative_Path
- (Switch : in out String_Access;
- Parent : String;
- Including_L_Switch : Boolean := True;
- Including_Non_Switch : Boolean := True;
- Including_RTS : Boolean := False);
- -- Test if Switch is a relative search path switch. If it is, fail if
- -- Parent is the empty string, otherwise prepend the path with Parent.
- -- This subprogram is only called when using project files. For gnatbind
- -- switches, Including_L_Switch is False, because the argument of the -L
- -- switch is not a path. If Including_RTS is True, process also switches
- -- --RTS=.
-
- function Path_Or_File_Name (Path : Path_Name_Type) return String;
- -- Returns a file name if -df is used, otherwise return a path name
-
----------------------
-- Marking Routines --
----------------------
diff --git a/gcc/ada/opt.adb b/gcc/ada/opt.adb
index aec6d77ee0b..a1528962b01 100644
--- a/gcc/ada/opt.adb
+++ b/gcc/ada/opt.adb
@@ -56,6 +56,8 @@ package body Opt is
External_Name_Exp_Casing_Config := External_Name_Exp_Casing;
External_Name_Imp_Casing_Config := External_Name_Imp_Casing;
Fast_Math_Config := Fast_Math;
+ Init_Or_Norm_Scalars_Config := Init_Or_Norm_Scalars;
+ Initialize_Scalars_Config := Initialize_Scalars;
Optimize_Alignment_Config := Optimize_Alignment;
Persistent_BSS_Mode_Config := Persistent_BSS_Mode;
Polling_Required_Config := Polling_Required;
@@ -86,6 +88,8 @@ package body Opt is
External_Name_Exp_Casing := Save.External_Name_Exp_Casing;
External_Name_Imp_Casing := Save.External_Name_Imp_Casing;
Fast_Math := Save.Fast_Math;
+ Init_Or_Norm_Scalars := Save.Init_Or_Norm_Scalars;
+ Initialize_Scalars := Save.Initialize_Scalars;
Optimize_Alignment := Save.Optimize_Alignment;
Optimize_Alignment_Local := Save.Optimize_Alignment_Local;
Persistent_BSS_Mode := Save.Persistent_BSS_Mode;
@@ -111,6 +115,8 @@ package body Opt is
Save.External_Name_Exp_Casing := External_Name_Exp_Casing;
Save.External_Name_Imp_Casing := External_Name_Imp_Casing;
Save.Fast_Math := Fast_Math;
+ Save.Init_Or_Norm_Scalars := Init_Or_Norm_Scalars;
+ Save.Initialize_Scalars := Initialize_Scalars;
Save.Optimize_Alignment := Optimize_Alignment;
Save.Optimize_Alignment_Local := Optimize_Alignment_Local;
Save.Persistent_BSS_Mode := Persistent_BSS_Mode;
@@ -175,6 +181,8 @@ package body Opt is
External_Name_Exp_Casing := External_Name_Exp_Casing_Config;
External_Name_Imp_Casing := External_Name_Imp_Casing_Config;
Fast_Math := Fast_Math_Config;
+ Init_Or_Norm_Scalars := Init_Or_Norm_Scalars_Config;
+ Initialize_Scalars := Initialize_Scalars_Config;
Optimize_Alignment := Optimize_Alignment_Config;
Optimize_Alignment_Local := False;
Persistent_BSS_Mode := Persistent_BSS_Mode_Config;
diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads
index 542b1f02551..9013d7d3dcd 100644
--- a/gcc/ada/opt.ads
+++ b/gcc/ada/opt.ads
@@ -861,6 +861,12 @@ package Opt is
-- This flag is set True if a No_Run_Time pragma is encountered. See
-- spec of Rtsfind for a full description of handling of this pragma.
+ No_Split_Units : Boolean := False;
+ -- GPRBUILD
+ -- Set to True with switch --no-split-units. When True, unit sources, spec,
+ -- body and subunits, must all be in the same project.This is checked after
+ -- each compilation.
+
No_Stdinc : Boolean := False;
-- GNAT, GNATBIND, GNATMAKE, GNATFIND, GNATXREF
-- Set to True if no default source search dirs added to search list
@@ -1042,6 +1048,10 @@ package Opt is
-- for GNATBIND and to False when using the -static option. The value of
-- this flag is set by Gnatbind.Scan_Bind_Arg.
+ Short_Circuit_And_Or : Boolean := False;
+ -- GNAT
+ -- Set True if a pragma Short_Circuit_And_Or applies to the current unit.
+
Sprint_Line_Limit : Nat := 72;
-- Limit values for chopping long lines in Sprint output, can be reset
-- by use of NNN parameter with -gnatG or -gnatD switches.
@@ -1547,6 +1557,18 @@ package Opt is
-- used to set the initial value of Fast_Math at the start of each new
-- compilation unit.
+ Init_Or_Norm_Scalars_Config : Boolean;
+ -- GNAT
+ -- This is the value of the configuration switch that is set by one
+ -- of the pragmas Initialize_Scalars or Normalize_Scalars.
+
+ Initialize_Scalars_Config : Boolean;
+ -- GNAT
+ -- This is the value of the configuration switch that is set by the
+ -- pragma Initialize_Scalars when it appears in the gnat.adc file.
+ -- This switch is not set when the pragma appears ahead of a given
+ -- unit, so it does not affect the compilation of other units.
+
Optimize_Alignment_Config : Character;
-- GNAT
-- This is the value of the configuration switch that controls the
@@ -1695,6 +1717,8 @@ private
External_Name_Exp_Casing : External_Casing_Type;
External_Name_Imp_Casing : External_Casing_Type;
Fast_Math : Boolean;
+ Init_Or_Norm_Scalars : Boolean;
+ Initialize_Scalars : Boolean;
Optimize_Alignment : Character;
Optimize_Alignment_Local : Boolean;
Persistent_BSS_Mode : Boolean;
diff --git a/gcc/ada/osint.adb b/gcc/ada/osint.adb
index 1b1f5085984..6265ede68d1 100644
--- a/gcc/ada/osint.adb
+++ b/gcc/ada/osint.adb
@@ -80,8 +80,8 @@ package body Osint is
-- Appends Suffix to Name and returns the new name
function OS_Time_To_GNAT_Time (T : OS_Time) return Time_Stamp_Type;
- -- Convert OS format time to GNAT format time stamp.
- -- Returns Empty_Time_Stamp if T is Invalid_Time
+ -- Convert OS format time to GNAT format time stamp. If T is Invalid_Time,
+ -- then returns Empty_Time_Stamp.
function Executable_Prefix return String_Ptr;
-- Returns the name of the root directory where the executable is stored.
@@ -91,8 +91,8 @@ package body Osint is
-- "/foo/bar/". Return "" if location is not recognized as described above.
function Update_Path (Path : String_Ptr) return String_Ptr;
- -- Update the specified path to replace the prefix with the location
- -- where GNAT is installed. See the file prefix.c in GCC for details.
+ -- Update the specified path to replace the prefix with the location where
+ -- GNAT is installed. See the file prefix.c in GCC for details.
procedure Locate_File
(N : File_Name_Type;
@@ -106,9 +106,11 @@ package body Osint is
-- if T = Source, Dir is an index into the Src_Search_Directories table.
-- Returns the File_Name_Type of the full file name if file found, or
-- No_File if not found.
+ --
-- On exit, Found is set to the file that was found, and Attr to a cache of
-- its attributes (at least those that have been computed so far). Reusing
-- the cache will save some system calls.
+ --
-- Attr is always reset in this call to Unknown_Attributes, even in case of
-- failure
@@ -136,6 +138,7 @@ package body Osint is
Path_Len : Integer) return String_Access;
-- Converts a C String to an Ada String. Are we doing this to avoid withing
-- Interfaces.C.Strings ???
+ -- Caller must free result.
function Include_Dir_Default_Prefix return String_Access;
-- Same as exported version, except returns a String_Access
@@ -239,8 +242,9 @@ package body Osint is
File : File_Name_Type;
Attr : aliased File_Attributes;
end record;
+
No_File_Info_Cache : constant File_Info_Cache :=
- (No_File, Unknown_Attributes);
+ (No_File, Unknown_Attributes);
package File_Name_Hash_Table is new GNAT.HTable.Simple_HTable (
Header_Num => File_Hash_Num,
@@ -584,13 +588,13 @@ package body Osint is
declare
Norm : String_Ptr := Normalize_Directory_Name (Dir);
- begin
+ begin
-- Do nothing if the directory is already in the list. This saves
-- system calls and avoid unneeded work
for D in Lib_Search_Directories.First ..
- Lib_Search_Directories.Last
+ Lib_Search_Directories.Last
loop
if Lib_Search_Directories.Table (D).all = Norm.all then
Free (Norm);
@@ -789,8 +793,12 @@ package body Osint is
-- Executable_Name --
---------------------
- function Executable_Name (Name : File_Name_Type) return File_Name_Type is
+ function Executable_Name
+ (Name : File_Name_Type;
+ Only_If_No_Suffix : Boolean := False) return File_Name_Type
+ is
Exec_Suffix : String_Access;
+ Add_Suffix : Boolean;
begin
if Name = No_File then
@@ -804,40 +812,63 @@ package body Osint is
Exec_Suffix := new String'(Name_Buffer (1 .. Name_Len));
end if;
- Get_Name_String (Name);
-
if Exec_Suffix'Length /= 0 then
- declare
- Buffer : String := Name_Buffer (1 .. Name_Len);
-
- begin
- -- Get the file name in canonical case to accept as is names
- -- ending with ".EXE" on VMS and Windows.
-
- Canonical_Case_File_Name (Buffer);
+ Get_Name_String (Name);
+
+ Add_Suffix := True;
+ if Only_If_No_Suffix then
+ for J in reverse 1 .. Name_Len loop
+ if Name_Buffer (J) = '.' then
+ Add_Suffix := False;
+ exit;
+
+ elsif Name_Buffer (J) = '/' or else
+ Name_Buffer (J) = Directory_Separator
+ then
+ exit;
+ end if;
+ end loop;
+ end if;
- -- If Executable does not end with the executable suffix, add it
+ if Add_Suffix then
+ declare
+ Buffer : String := Name_Buffer (1 .. Name_Len);
- if Buffer'Length <= Exec_Suffix'Length
- or else
- Buffer (Buffer'Last - Exec_Suffix'Length + 1 .. Buffer'Last)
- /= Exec_Suffix.all
- then
- Name_Buffer (Name_Len + 1 .. Name_Len + Exec_Suffix'Length) :=
- Exec_Suffix.all;
- Name_Len := Name_Len + Exec_Suffix'Length;
- Free (Exec_Suffix);
- return Name_Find;
- end if;
- end;
+ begin
+ -- Get the file name in canonical case to accept as is names
+ -- ending with ".EXE" on VMS and Windows.
+
+ Canonical_Case_File_Name (Buffer);
+
+ -- If Executable does not end with the executable suffix, add
+ -- it.
+
+ if Buffer'Length <= Exec_Suffix'Length
+ or else
+ Buffer (Buffer'Last - Exec_Suffix'Length + 1 .. Buffer'Last)
+ /= Exec_Suffix.all
+ then
+ Name_Buffer
+ (Name_Len + 1 .. Name_Len + Exec_Suffix'Length) :=
+ Exec_Suffix.all;
+ Name_Len := Name_Len + Exec_Suffix'Length;
+ Free (Exec_Suffix);
+ return Name_Find;
+ end if;
+ end;
+ end if;
end if;
Free (Exec_Suffix);
return Name;
end Executable_Name;
- function Executable_Name (Name : String) return String is
+ function Executable_Name
+ (Name : String;
+ Only_If_No_Suffix : Boolean := False) return String
+ is
Exec_Suffix : String_Access;
+ Add_Suffix : Boolean;
Canonical_Name : String := Name;
begin
@@ -848,30 +879,50 @@ package body Osint is
Exec_Suffix := new String'(Name_Buffer (1 .. Name_Len));
end if;
- declare
- Suffix : constant String := Exec_Suffix.all;
-
- begin
+ if Exec_Suffix'Length = 0 then
Free (Exec_Suffix);
- Canonical_Case_File_Name (Canonical_Name);
+ return Name;
+
+ else
+ declare
+ Suffix : constant String := Exec_Suffix.all;
- if Suffix'Length /= 0
- and then
- (Canonical_Name'Length <= Suffix'Length
+ begin
+ Free (Exec_Suffix);
+ Canonical_Case_File_Name (Canonical_Name);
+
+ Add_Suffix := True;
+ if Only_If_No_Suffix then
+ for J in reverse Canonical_Name'Range loop
+ if Canonical_Name (J) = '.' then
+ Add_Suffix := False;
+ exit;
+
+ elsif Canonical_Name (J) = '/' or else
+ Canonical_Name (J) = Directory_Separator
+ then
+ exit;
+ end if;
+ end loop;
+ end if;
+
+ if Add_Suffix and then
+ (Canonical_Name'Length <= Suffix'Length
or else Canonical_Name (Canonical_Name'Last - Suffix'Length + 1
- .. Canonical_Name'Last) /= Suffix)
- then
- declare
- Result : String (1 .. Name'Length + Suffix'Length);
- begin
- Result (1 .. Name'Length) := Name;
- Result (Name'Length + 1 .. Result'Last) := Suffix;
- return Result;
- end;
- else
- return Name;
- end if;
- end;
+ .. Canonical_Name'Last) /= Suffix)
+ then
+ declare
+ Result : String (1 .. Name'Length + Suffix'Length);
+ begin
+ Result (1 .. Name'Length) := Name;
+ Result (Name'Length + 1 .. Result'Last) := Suffix;
+ return Result;
+ end;
+ else
+ return Name;
+ end if;
+ end;
+ end if;
end Executable_Name;
-----------------------
@@ -1002,10 +1053,13 @@ package body Osint is
-----------------
function File_Length
- (Name : C_File_Name; Attr : access File_Attributes) return Long_Integer
+ (Name : C_File_Name;
+ Attr : access File_Attributes) return Long_Integer
is
function Internal
- (F : Integer; N : C_File_Name; A : System.Address) return Long_Integer;
+ (F : Integer;
+ N : C_File_Name;
+ A : System.Address) return Long_Integer;
pragma Import (C, Internal, "__gnat_file_length_attr");
begin
return Internal (-1, Name, Attr.all'Address);
@@ -1016,7 +1070,8 @@ package body Osint is
---------------------
function File_Time_Stamp
- (Name : C_File_Name; Attr : access File_Attributes) return OS_Time
+ (Name : C_File_Name;
+ Attr : access File_Attributes) return OS_Time
is
function Internal (N : C_File_Name; A : System.Address) return OS_Time;
pragma Import (C, Internal, "__gnat_file_time_name_attr");
@@ -1024,6 +1079,21 @@ package body Osint is
return Internal (Name, Attr.all'Address);
end File_Time_Stamp;
+ function File_Time_Stamp
+ (Name : Path_Name_Type;
+ Attr : access File_Attributes) return Time_Stamp_Type
+ is
+ begin
+ if Name = No_Path then
+ return Empty_Time_Stamp;
+ end if;
+
+ Get_Name_String (Name);
+ Name_Buffer (Name_Len + 1) := ASCII.NUL;
+ return OS_Time_To_GNAT_Time
+ (File_Time_Stamp (Name_Buffer'Address, Attr));
+ end File_Time_Stamp;
+
----------------
-- File_Stamp --
----------------
@@ -1036,13 +1106,13 @@ package body Osint is
Get_Name_String (Name);
- -- File_Time_Stamp will always return Invalid_Time if the file does not
- -- exist, and OS_Time_To_GNAT_Time will convert this value to
- -- Empty_Time_Stamp. Therefore we do not need to first test whether the
- -- file actually exists, which saves a system call.
+ -- File_Time_Stamp will always return Invalid_Time if the file does
+ -- not exist, and OS_Time_To_GNAT_Time will convert this value to
+ -- Empty_Time_Stamp. Therefore we do not need to first test whether
+ -- the file actually exists, which saves a system call.
return OS_Time_To_GNAT_Time
- (File_Time_Stamp (Name_Buffer (1 .. Name_Len)));
+ (File_Time_Stamp (Name_Buffer (1 .. Name_Len)));
end File_Stamp;
function File_Stamp (Name : Path_Name_Type) return Time_Stamp_Type is
@@ -1084,9 +1154,9 @@ package body Osint is
begin
-- If we are looking for a config file, look only in the current
- -- directory, i.e. return input argument unchanged. Also look
- -- only in the current directory if we are looking for a .dg
- -- file (happens in -gnatD mode).
+ -- directory, i.e. return input argument unchanged. Also look only in
+ -- the curren directory if we are looking for a .dg file (happens in
+ -- -gnatD mode).
if T = Config
or else (Debug_Generated_Code
@@ -2392,10 +2462,13 @@ package body Osint is
if Opt.Check_Object_Consistency then
-- On most systems, this does not result in an extra system call
- Current_Full_Lib_Stamp := OS_Time_To_GNAT_Time
- (File_Time_Stamp (Name_Buffer'Address, Lib_File_Attr));
+
+ Current_Full_Lib_Stamp :=
+ OS_Time_To_GNAT_Time
+ (File_Time_Stamp (Name_Buffer'Address, Lib_File_Attr));
-- ??? One system call here
+
Current_Full_Obj_Stamp := File_Stamp (Current_Full_Obj_Name);
if Current_Full_Obj_Stamp (1) = ' ' then
@@ -2710,6 +2783,7 @@ package body Osint is
is
File : File_Name_Type;
Attr : aliased File_Attributes;
+
begin
if not File_Cache_Enabled then
Find_File (N, T, File, Attr'Access);
@@ -2722,8 +2796,9 @@ package body Osint is
else
Get_Name_String (File);
Name_Buffer (Name_Len + 1) := ASCII.NUL;
- return OS_Time_To_GNAT_Time
- (File_Time_Stamp (Name_Buffer'Address, Attr'Access));
+ return
+ OS_Time_To_GNAT_Time
+ (File_Time_Stamp (Name_Buffer'Address, Attr'Access));
end if;
end Smart_File_Stamp;
@@ -2757,8 +2832,10 @@ package body Osint is
begin
if not File_Cache_Enabled then
Find_File (N, T, Info.File, Info.Attr'Access);
+
else
Info := File_Name_Hash_Table.Get (N);
+
if Info.File = No_File then
Find_File (N, T, Info.File, Info.Attr'Access);
File_Name_Hash_Table.Set (N, Info);
@@ -2801,8 +2878,7 @@ package body Osint is
if Is_Directory_Separator (Name_Buffer (J)) then
- -- Return the part of Name that follows this last directory
- -- separator.
+ -- Return part of Name that follows this last directory separator
Name_Buffer (1 .. Name_Len - J) := Name_Buffer (J + 1 .. Name_Len);
Name_Len := Name_Len - J;
@@ -2849,7 +2925,7 @@ package body Osint is
Prefix_Flag : Integer) return Address;
pragma Import (C, To_Canonical_Dir_Spec, "__gnat_to_canonical_dir_spec");
- C_Host_Dir : String (1 .. Host_Dir'Length + 1);
+ C_Host_Dir : String (1 .. Host_Dir'Length + 1);
Canonical_Dir_Addr : Address;
Canonical_Dir_Len : Integer;
@@ -2862,6 +2938,7 @@ package body Osint is
else
Canonical_Dir_Addr := To_Canonical_Dir_Spec (C_Host_Dir'Address, 0);
end if;
+
Canonical_Dir_Len := C_String_Length (Canonical_Dir_Addr);
if Canonical_Dir_Len = 0 then
diff --git a/gcc/ada/osint.ads b/gcc/ada/osint.ads
index 34b3f642fee..ae827ba286b 100644
--- a/gcc/ada/osint.ads
+++ b/gcc/ada/osint.ads
@@ -30,8 +30,8 @@ with Namet; use Namet;
with Types; use Types;
with System.Storage_Elements;
-with System.OS_Lib; use System.OS_Lib;
-with System; use System;
+with System.OS_Lib; use System.OS_Lib;
+with System; use System;
pragma Elaborate_All (System.OS_Lib);
-- For the call to function Get_Target_Object_Suffix in the private part
@@ -147,13 +147,17 @@ package Osint is
-- Strips the suffix (the last '.' and whatever comes after it) from Name.
-- Returns the stripped name.
- function Executable_Name (Name : File_Name_Type) return File_Name_Type;
+ function Executable_Name
+ (Name : File_Name_Type;
+ Only_If_No_Suffix : Boolean := False) return File_Name_Type;
-- Given a file name it adds the appropriate suffix at the end so that
-- it becomes the name of the executable on the system at end. For
-- instance under DOS it adds the ".exe" suffix, whereas under UNIX no
-- suffix is added.
- function Executable_Name (Name : String) return String;
+ function Executable_Name
+ (Name : String;
+ Only_If_No_Suffix : Boolean := False) return String;
-- Same as above, with String parameters
function File_Stamp (Name : File_Name_Type) return Time_Stamp_Type;
@@ -207,9 +211,9 @@ package Osint is
function To_Host_Dir_Spec
(Canonical_Dir : String;
Prefix_Style : Boolean) return String_Access;
- -- Convert a canonical syntax directory specification to host syntax.
- -- The Prefix_Style flag is currently ignored but should be set to
- -- False.
+ -- Convert a canonical syntax directory specification to host syntax. The
+ -- Prefix_Style flag is currently ignored but should be set to False.
+ -- Note that the caller must free result.
function To_Host_File_Spec
(Canonical_File : String) return String_Access;
@@ -234,10 +238,12 @@ package Osint is
---------------------
-- File attributes --
---------------------
+
-- The following subprograms offer services similar to those found in
-- System.OS_Lib, but with the ability to extra multiple information from
-- a single system call, depending on the system. This can result in fewer
-- system calls when reused.
+
-- In all these subprograms, the requested value is either read from the
-- File_Attributes parameter (resulting in no system call), or computed
-- from the disk and then cached in the File_Attributes parameter (possibly
@@ -249,27 +255,38 @@ package Osint is
-- This must be initialized to Unknown_Attributes prior to the first call.
function Is_Directory
- (Name : C_File_Name; Attr : access File_Attributes) return Boolean;
+ (Name : C_File_Name;
+ Attr : access File_Attributes) return Boolean;
function Is_Regular_File
- (Name : C_File_Name; Attr : access File_Attributes) return Boolean;
+ (Name : C_File_Name;
+ Attr : access File_Attributes) return Boolean;
function Is_Symbolic_Link
- (Name : C_File_Name; Attr : access File_Attributes) return Boolean;
+ (Name : C_File_Name;
+ Attr : access File_Attributes) return Boolean;
-- Return the type of the file,
function File_Length
- (Name : C_File_Name; Attr : access File_Attributes) return Long_Integer;
+ (Name : C_File_Name;
+ Attr : access File_Attributes) return Long_Integer;
-- Return the length (number of bytes) of the file
function File_Time_Stamp
- (Name : C_File_Name; Attr : access File_Attributes) return OS_Time;
+ (Name : C_File_Name;
+ Attr : access File_Attributes) return OS_Time;
+ function File_Time_Stamp
+ (Name : Path_Name_Type;
+ Attr : access File_Attributes) return Time_Stamp_Type;
-- Return the time stamp of the file
function Is_Readable_File
- (Name : C_File_Name; Attr : access File_Attributes) return Boolean;
+ (Name : C_File_Name;
+ Attr : access File_Attributes) return Boolean;
function Is_Executable_File
- (Name : C_File_Name; Attr : access File_Attributes) return Boolean;
+ (Name : C_File_Name;
+ Attr : access File_Attributes) return Boolean;
function Is_Writable_File
- (Name : C_File_Name; Attr : access File_Attributes) return Boolean;
+ (Name : C_File_Name;
+ Attr : access File_Attributes) return Boolean;
-- Return the access rights for the file
-------------------------
@@ -436,6 +453,7 @@ package Osint is
-- The source file directory lookup penalty is incurred every single time
-- the routines are called unless you have previously called
-- Source_File_Data (Cache => True). See below.
+ --
-- The procedural version also returns some file attributes for the ALI
-- file (to save on system calls later on).
@@ -468,11 +486,11 @@ package Osint is
-- Representation of Library Information --
-------------------------------------------
- -- Associated with each compiled source file is library information,
- -- a string of bytes whose exact format is described in the body of
- -- Lib.Writ. Compiling a source file generates this library information
- -- for the compiled unit, and access the library information for units
- -- that were compiled previously on which the unit being compiled depends.
+ -- Associated with each compiled source file is library information, a
+ -- string of bytes whose exact format is described in the body of Lib.Writ.
+ -- Compiling a source file generates this library information for the
+ -- compiled unit, and access the library information for units that were
+ -- compiled previously on which the unit being compiled depends.
-- How this information is stored is up to the implementation of this
-- package. At the interface level, this information is simply associated
@@ -524,15 +542,14 @@ package Osint is
-- include any directory information. The implementation is responsible
-- for searching for the file in appropriate directories.
--
- -- If Opt.Check_Object_Consistency is set to True then this routine
- -- checks whether the object file corresponding to the Lib_File is
- -- consistent with it. The object file is inconsistent if the object
- -- does not exist or if it has an older time stamp than Lib_File.
- -- This check is not performed when the Lib_File is "locked" (i.e.
- -- read/only) because in this case the object file may be buried
- -- in a library. In case of inconsistencies Read_Library_Info
- -- behaves as if it did not find Lib_File (namely if Fatal_Err is
- -- False, null is returned).
+ -- If Opt.Check_Object_Consistency is set to True then this routine checks
+ -- whether the object file corresponding to the Lib_File is consistent with
+ -- it. The object file is inconsistent if the object does not exist or if
+ -- it has an older time stamp than Lib_File. This check is not performed
+ -- when the Lib_File is "locked" (i.e. read/only) because in this case the
+ -- object file may be buried in a library. In case of inconsistencies
+ -- Read_Library_Info behaves as if it did not find Lib_File (namely if
+ -- Fatal_Err is False, null is returned).
function Read_Library_Info_From_Full
(Full_Lib_File : File_Name_Type;
@@ -718,15 +735,17 @@ private
-- detected, the file being written is deleted, and a fatal error is
-- signalled.
- File_Attributes_Size : constant Integer := 50;
+ File_Attributes_Size : constant Natural := 24;
-- This should be big enough to fit a "struct file_attributes" on any
- -- system. It doesn't matter if it is too big (which avoids the need for
- -- either mapping the struct exactly or importing the sizeof from C, which
- -- would result in dynamic code)
+ -- system. It doesn't cause any malfunction if it is too big (which avoids
+ -- the need for either mapping the struct exactly or importing the sizeof
+ -- from C, which would result in dynamic code). However, it does waste
+ -- space (e.g. when a component of this type appears in a record, if it is
+ -- unnecessarily large.
type File_Attributes is
array (1 .. File_Attributes_Size)
- of System.Storage_Elements.Storage_Element;
+ of System.Storage_Elements.Storage_Element;
for File_Attributes'Alignment use Standard'Maximum_Alignment;
Unknown_Attributes : constant File_Attributes := (others => 0);
diff --git a/gcc/ada/par-prag.adb b/gcc/ada/par-prag.adb
index eb77f860b4f..8d823cedd61 100644
--- a/gcc/ada/par-prag.adb
+++ b/gcc/ada/par-prag.adb
@@ -974,10 +974,11 @@ begin
-- The one argument ON/OFF case is processed by the parser, since it may
-- control parser warnings as well as semantic warnings, and in any case
-- we want to be absolutely sure that the range in the warnings table is
- -- set well before any semantic analysis is performed.
+ -- set well before any semantic analysis is performed. Note that we
+ -- ignore this pragma if debug flag -gnatd.i is set.
when Pragma_Warnings =>
- if Arg_Count = 1 then
+ if Arg_Count = 1 and then not Debug_Flag_Dot_I then
Check_No_Identifier (Arg1);
declare
@@ -1171,6 +1172,7 @@ begin
Pragma_Share_Generic |
Pragma_Shared |
Pragma_Shared_Passive |
+ Pragma_Short_Circuit_And_Or |
Pragma_Storage_Size |
Pragma_Storage_Unit |
Pragma_Static_Elaboration_Desired |
diff --git a/gcc/ada/par_sco.adb b/gcc/ada/par_sco.adb
index ea7726395a1..e6d71dd525b 100644
--- a/gcc/ada/par_sco.adb
+++ b/gcc/ada/par_sco.adb
@@ -989,7 +989,12 @@ package body Par_SCO is
Handler : Node_Id;
begin
- if Present (N) then
+
+ -- For package bodies without a statement part, the parser adds an empty
+ -- one, to normalize the representation. The null statement therein,
+ -- which does not come from source, does not get a SCO.
+
+ if Present (N) and then Comes_From_Source (N) then
Traverse_Declarations_Or_Statements (Statements (N));
if Present (Exception_Handlers (N)) then
diff --git a/gcc/ada/prj-attr.adb b/gcc/ada/prj-attr.adb
index 13f0904665a..ebb19503663 100644
--- a/gcc/ada/prj-attr.adb
+++ b/gcc/ada/prj-attr.adb
@@ -179,6 +179,8 @@ package body Prj.Attr is
"Sapath_syntax#" &
"Saobject_file_suffix#" &
"Laobject_file_switches#" &
+ "Lamulti_unit_switches#" &
+ "Samulti_unit_object_separator#" &
-- Configuration - Mapping files
@@ -190,8 +192,10 @@ package body Prj.Attr is
"Laconfig_file_switches#" &
"Saconfig_body_file_name#" &
- "Saconfig_spec_file_name#" &
+ "Saconfig_body_file_name_index#" &
"Saconfig_body_file_name_pattern#" &
+ "Saconfig_spec_file_name#" &
+ "Saconfig_spec_file_name_index#" &
"Saconfig_spec_file_name_pattern#" &
"Saconfig_file_unique#" &
diff --git a/gcc/ada/prj-attr.ads b/gcc/ada/prj-attr.ads
index a8f9e15412e..6fad3f0a0dc 100644
--- a/gcc/ada/prj-attr.ads
+++ b/gcc/ada/prj-attr.ads
@@ -46,15 +46,27 @@ package Prj.Attr is
type Attribute_Kind is
(Unknown,
+ -- The attribute does not exist
+
Single,
+ -- Single variable attribute (not an associative array)
+
Associative_Array,
+ -- Associative array attribute with a case sensitive index
+
Optional_Index_Associative_Array,
+ -- Associative array attribute with a case sensitive index and an
+ -- optional source index.
+
Case_Insensitive_Associative_Array,
+ -- Associative array attribute with a case insensitive index
+
Optional_Index_Case_Insensitive_Associative_Array);
+ -- Associative array attribute with a case insensitive index and an
+ -- optional source index.
-- Characteristics of an attribute. Optional_Index indicates that there
-- may be an optional index in the index of the associative array, as in
-- for Switches ("files.ada" at 2) use ...
- -- Above character literals should be documented ???
subtype Defined_Attribute_Kind is Attribute_Kind
range Single .. Optional_Index_Case_Insensitive_Associative_Array;
diff --git a/gcc/ada/prj-conf.adb b/gcc/ada/prj-conf.adb
index bcf434b15e1..30823a3862d 100644
--- a/gcc/ada/prj-conf.adb
+++ b/gcc/ada/prj-conf.adb
@@ -1188,8 +1188,11 @@ package body Prj.Conf is
Index : String := "";
Pkg : Project_Node_Id := Empty_Node)
is
- Attr : Project_Node_Id;
- Val : Name_Id := No_Name;
+ Attr : Project_Node_Id;
+ pragma Unreferenced (Attr);
+
+ Expr : Name_Id := No_Name;
+ Val : Name_Id := No_Name;
Parent : Project_Node_Id := Config_File;
begin
if Index /= "" then
@@ -1202,24 +1205,21 @@ package body Prj.Conf is
Parent := Pkg;
end if;
+ Name_Len := Value'Length;
+ Name_Buffer (1 .. Name_Len) := Value;
+ Expr := Name_Find;
+
Attr := Create_Attribute
(Tree => Project_Tree,
Prj_Or_Pkg => Parent,
Name => Name,
Index_Name => Val,
- Kind => Prj.Single);
-
- Name_Len := Value'Length;
- Name_Buffer (1 .. Name_Len) := Value;
- Val := Name_Find;
-
- Set_Expression_Of
- (Attr, Project_Tree,
- Enclose_In_Expression
- (Create_Literal_String (Val, Project_Tree),
- Project_Tree));
+ Kind => Prj.Single,
+ Value => Create_Literal_String (Expr, Project_Tree));
end Create_Attribute;
+ -- Local variables
+
Name : Name_Id;
Naming : Project_Node_Id;
diff --git a/gcc/ada/prj-env.adb b/gcc/ada/prj-env.adb
index c5182abea09..f7fc668dd8f 100644
--- a/gcc/ada/prj-env.adb
+++ b/gcc/ada/prj-env.adb
@@ -410,7 +410,7 @@ package body Prj.Env is
end loop;
if Add_It then
- Source_Path_Table.Append (Source_Paths, Source_Dir.Value);
+ Source_Path_Table.Append (Source_Paths, Source_Dir.Display_Value);
end if;
-- Next source directory
diff --git a/gcc/ada/prj-ext.adb b/gcc/ada/prj-ext.adb
index 8c7a5d95d96..fe6216f82fa 100644
--- a/gcc/ada/prj-ext.adb
+++ b/gcc/ada/prj-ext.adb
@@ -213,9 +213,9 @@ package body Prj.Ext is
declare
New_Dir : constant String :=
- Normalize_Pathname
- (Name_Buffer (First .. Last),
- Resolve_Links => Opt.Follow_Links_For_Dirs);
+ Normalize_Pathname
+ (Name_Buffer (First .. Last),
+ Resolve_Links => Opt.Follow_Links_For_Dirs);
begin
-- If the absolute path was resolved and is different from
diff --git a/gcc/ada/prj-makr.adb b/gcc/ada/prj-makr.adb
index 0f91936b1b7..50cd0703d67 100644
--- a/gcc/ada/prj-makr.adb
+++ b/gcc/ada/prj-makr.adb
@@ -39,8 +39,9 @@ with Table; use Table;
with Ada.Characters.Handling; use Ada.Characters.Handling;
with GNAT.Directory_Operations; use GNAT.Directory_Operations;
-with System.Case_Util; use System.Case_Util;
+with System.Case_Util; use System.Case_Util;
with System.CRTL;
+with System.HTable;
package body Prj.Makr is
@@ -170,6 +171,16 @@ package body Prj.Makr is
-- in the source attribute and package Naming of the project file, or in
-- the pragmas Source_File_Name in the configuration pragmas file.
+ package Source_Files is new System.HTable.Simple_HTable
+ (Header_Num => Prj.Header_Num,
+ Element => Boolean,
+ No_Element => False,
+ Key => Name_Id,
+ Hash => Prj.Hash,
+ Equal => "=");
+ -- Hash table to keep track of source file names, to avoid putting several
+ -- times the same file name in case of multi-unit files.
+
---------
-- Dup --
---------
@@ -602,15 +613,20 @@ package body Prj.Makr is
In_Tree => Tree);
begin
- -- Add source file name to the source list file
+ -- Add source file name to the source list file if it is not
+ -- already there.
- Get_Name_String (Current_Source.File_Name);
- Add_Char_To_Name_Buffer (ASCII.LF);
- if Write (Source_List_FD,
- Name_Buffer (1)'Address,
- Name_Len) /= Name_Len
- then
- Prj.Com.Fail ("disk full");
+ if not Source_Files.Get (Current_Source.File_Name) then
+ Source_Files.Set (Current_Source.File_Name, True);
+ Get_Name_String (Current_Source.File_Name);
+ Add_Char_To_Name_Buffer (ASCII.LF);
+
+ if Write (Source_List_FD,
+ Name_Buffer (1)'Address,
+ Name_Len) /= Name_Len
+ then
+ Prj.Com.Fail ("disk full");
+ end if;
end if;
-- For an Ada source, add entry in package Naming
@@ -854,7 +870,7 @@ package body Prj.Makr is
-- Fail if parsing was not successful
if No (Project_Node) then
- Fail ("parsing of existing project file failed");
+ Prj.Com.Fail ("parsing of existing project file failed");
else
-- If parsing was successful, remove the components that are
diff --git a/gcc/ada/prj-nmsc.adb b/gcc/ada/prj-nmsc.adb
index 5e76bce58ac..35d7e041bb6 100644
--- a/gcc/ada/prj-nmsc.adb
+++ b/gcc/ada/prj-nmsc.adb
@@ -655,7 +655,7 @@ package body Prj.Nmsc is
Location, Project);
Error_Msg_Name_1 := Project.Name;
- Error_Msg_Name_2 := Name_Id (Path.Name);
+ Error_Msg_Name_2 := Name_Id (Path.Display_Name);
Error_Msg
(Data.Flags, "\ project %%, %%", Location, Project);
@@ -777,6 +777,10 @@ package body Prj.Nmsc is
Source_Paths_Htable.Set (Data.Tree.Source_Paths_HT, Path.Name, Id);
end if;
+ if Index /= 0 then
+ Project.Has_Multi_Unit_Sources := True;
+ end if;
+
-- Add the source to the language list
Id.Next_In_Lang := Lang_Id.First_Source;
@@ -1431,6 +1435,34 @@ package body Prj.Nmsc is
From_List => Element.Value.Values,
In_Tree => Data.Tree);
+ when Name_Multi_Unit_Switches =>
+ Put (Into_List =>
+ Lang_Index.Config.Multi_Unit_Switches,
+ From_List => Element.Value.Values,
+ In_Tree => Data.Tree);
+
+ when Name_Multi_Unit_Object_Separator =>
+ Get_Name_String (Element.Value.Value);
+
+ if Name_Len /= 1 then
+ Error_Msg
+ (Data.Flags,
+ "multi-unit object separator must have " &
+ "a single character",
+ Element.Value.Location, Project);
+
+ elsif Name_Buffer (1) = ' ' then
+ Error_Msg
+ (Data.Flags,
+ "multi-unit object separator cannot be " &
+ "a space",
+ Element.Value.Location, Project);
+
+ else
+ Lang_Index.Config.Multi_Unit_Object_Separator :=
+ Name_Buffer (1);
+ end if;
+
when Name_Path_Syntax =>
begin
Lang_Index.Config.Path_Syntax :=
@@ -1552,10 +1584,18 @@ package body Prj.Nmsc is
Lang_Index.Config.Config_Body :=
Element.Value.Value;
+ when Name_Config_Body_File_Name_Index =>
+
+ -- Attribute Config_Body_File_Name_Index
+ -- ( < Language > )
+
+ Lang_Index.Config.Config_Body_Index :=
+ Element.Value.Value;
+
when Name_Config_Body_File_Name_Pattern =>
-- Attribute Config_Body_File_Name_Pattern
- -- (<language>)
+ -- (<language>)
Lang_Index.Config.Config_Body_Pattern :=
Element.Value.Value;
@@ -1567,10 +1607,18 @@ package body Prj.Nmsc is
Lang_Index.Config.Config_Spec :=
Element.Value.Value;
+ when Name_Config_Spec_File_Name_Index =>
+
+ -- Attribute Config_Spec_File_Name_Index
+ -- ( < Language > )
+
+ Lang_Index.Config.Config_Spec_Index :=
+ Element.Value.Value;
+
when Name_Config_Spec_File_Name_Pattern =>
-- Attribute Config_Spec_File_Name_Pattern
- -- (<language>)
+ -- (<language>)
Lang_Index.Config.Config_Spec_Pattern :=
Element.Value.Value;
@@ -2472,6 +2520,12 @@ package body Prj.Nmsc is
Project.Decl.Attributes,
Data.Tree);
+ Library_Interface : constant Prj.Variable_Value :=
+ Prj.Util.Value_Of
+ (Snames.Name_Library_Interface,
+ Project.Decl.Attributes,
+ Data.Tree);
+
List : String_List_Id;
Element : String_Element;
Name : File_Name_Type;
@@ -2556,22 +2610,90 @@ package body Prj.Nmsc is
Project.Interfaces_Defined := True;
- elsif Project.Extends /= No_Project then
- Project.Interfaces_Defined := Project.Extends.Interfaces_Defined;
+ elsif Project.Library and then not Library_Interface.Default then
+
+ -- Set In_Interfaces to False for all sources. It will be set to True
+ -- later for the sources in the Library_Interface list.
- if Project.Interfaces_Defined then
- Iter := For_Each_Source (Data.Tree, Project);
+ Project_2 := Project;
+ while Project_2 /= No_Project loop
+ Iter := For_Each_Source (Data.Tree, Project_2);
loop
Source := Prj.Element (Iter);
exit when Source = No_Source;
-
- if not Source.Declared_In_Interfaces then
- Source.In_Interfaces := False;
- end if;
-
+ Source.In_Interfaces := False;
Next (Iter);
end loop;
- end if;
+
+ Project_2 := Project_2.Extends;
+ end loop;
+
+ List := Library_Interface.Values;
+ while List /= Nil_String loop
+ Element := Data.Tree.String_Elements.Table (List);
+ Get_Name_String (Element.Value);
+ To_Lower (Name_Buffer (1 .. Name_Len));
+ Name := Name_Find;
+
+ Project_2 := Project;
+ Big_Loop_2 :
+ while Project_2 /= No_Project loop
+ Iter := For_Each_Source (Data.Tree, Project_2);
+
+ loop
+ Source := Prj.Element (Iter);
+ exit when Source = No_Source;
+
+ if Source.Unit /= No_Unit_Index and then
+ Source.Unit.Name = Name_Id (Name)
+ then
+ if not Source.Locally_Removed then
+ Source.In_Interfaces := True;
+ Source.Declared_In_Interfaces := True;
+
+ Other := Other_Part (Source);
+
+ if Other /= No_Source then
+ Other.In_Interfaces := True;
+ Other.Declared_In_Interfaces := True;
+ end if;
+
+ if Current_Verbosity = High then
+ Write_Str (" interface: ");
+ Write_Line (Get_Name_String (Source.Path.Name));
+ end if;
+ end if;
+
+ exit Big_Loop_2;
+ end if;
+
+ Next (Iter);
+ end loop;
+
+ Project_2 := Project_2.Extends;
+ end loop Big_Loop_2;
+
+ List := Element.Next;
+ end loop;
+
+ Project.Interfaces_Defined := True;
+
+ elsif Project.Extends /= No_Project
+ and then Project.Extends.Interfaces_Defined
+ then
+ Project.Interfaces_Defined := True;
+
+ Iter := For_Each_Source (Data.Tree, Project);
+ loop
+ Source := Prj.Element (Iter);
+ exit when Source = No_Source;
+
+ if not Source.Declared_In_Interfaces then
+ Source.In_Interfaces := False;
+ end if;
+
+ Next (Iter);
+ end loop;
end if;
end Check_Interfaces;
@@ -6785,12 +6907,15 @@ package body Prj.Nmsc is
exit when Last = 0;
- -- ??? Duplicate system call here, we just did a a
- -- similar one. Maybe Ada.Directories would be more
- -- appropriate here.
+ -- In fast project loading mode (without -eL), the user
+ -- guarantees that no directory has a name which is a
+ -- valid source name, so we can avoid doing a system call
+ -- here. This provides a very significant speed up on
+ -- slow file systems (remote files for instance).
- if Is_Regular_File
- (Source_Directory & Name (1 .. Last))
+ if not Opt.Follow_Links_For_Files
+ or else Is_Regular_File
+ (Source_Directory & Name (1 .. Last))
then
if Current_Verbosity = High then
Write_Str (" Checking ");
diff --git a/gcc/ada/prj-part.adb b/gcc/ada/prj-part.adb
index 7702f540930..c733f38365c 100644
--- a/gcc/ada/prj-part.adb
+++ b/gcc/ada/prj-part.adb
@@ -2083,7 +2083,7 @@ package body Prj.Part is
GNAT.OS_Lib.Normalize_Pathname
(Result.all,
Directory => Directory,
- Resolve_Links => False,
+ Resolve_Links => Opt.Follow_Links_For_Files,
Case_Sensitive => True);
begin
Free (Result);
diff --git a/gcc/ada/prj-pp.adb b/gcc/ada/prj-pp.adb
index cc88f8e5eb5..d318c1192c5 100644
--- a/gcc/ada/prj-pp.adb
+++ b/gcc/ada/prj-pp.adb
@@ -532,6 +532,12 @@ package body Prj.PP is
Write_String (" (");
Output_String
(Associative_Array_Index_Of (Node, In_Tree));
+
+ if Source_Index_Of (Node, In_Tree) /= 0 then
+ Write_String (" at");
+ Write_String (Source_Index_Of (Node, In_Tree)'Img);
+ end if;
+
Write_String (")");
end if;
@@ -574,11 +580,6 @@ package body Prj.PP is
Output_Attribute_Name (Name_Of (Node, In_Tree));
end if;
- if Source_Index_Of (Node, In_Tree) /= 0 then
- Write_String (" at");
- Write_String (Source_Index_Of (Node, In_Tree)'Img);
- end if;
-
Write_String (";");
Write_End_Of_Line_Comment (Node);
Print (First_Comment_After (Node, In_Tree), Indent);
diff --git a/gcc/ada/prj-proc.adb b/gcc/ada/prj-proc.adb
index 0cd20c8f19d..49841522dc9 100644
--- a/gcc/ada/prj-proc.adb
+++ b/gcc/ada/prj-proc.adb
@@ -1869,9 +1869,16 @@ package body Prj.Proc is
else
declare
Index_Name : Name_Id :=
- Associative_Array_Index_Of
- (Current_Item, From_Project_Node_Tree);
- The_Array : Array_Id;
+ Associative_Array_Index_Of
+ (Current_Item,
+ From_Project_Node_Tree);
+
+ Source_Index : constant Int :=
+ Source_Index_Of
+ (Current_Item,
+ From_Project_Node_Tree);
+
+ The_Array : Array_Id;
The_Array_Element : Array_Element_Id :=
No_Array_Element;
@@ -1889,9 +1896,9 @@ package body Prj.Proc is
if Pkg /= No_Package then
The_Array :=
In_Tree.Packages.Table (Pkg).Decl.Arrays;
-
else
- The_Array := Project.Decl.Arrays;
+ The_Array :=
+ Project.Decl.Arrays;
end if;
while
@@ -1900,8 +1907,8 @@ package body Prj.Proc is
In_Tree.Arrays.Table (The_Array).Name /=
Current_Item_Name
loop
- The_Array := In_Tree.Arrays.Table
- (The_Array).Next;
+ The_Array :=
+ In_Tree.Arrays.Table (The_Array).Next;
end loop;
-- If the array cannot be found, create a new entry
@@ -1943,12 +1950,15 @@ package body Prj.Proc is
end if;
-- Look in the list, if any, to find an element
- -- with the same index.
+ -- with the same index and same source index.
while The_Array_Element /= No_Array_Element
and then
- In_Tree.Array_Elements.Table
+ (In_Tree.Array_Elements.Table
(The_Array_Element).Index /= Index_Name
+ or else
+ In_Tree.Array_Elements.Table
+ (The_Array_Element).Src_Index /= Source_Index)
loop
The_Array_Element :=
In_Tree.Array_Elements.Table
@@ -1962,23 +1972,23 @@ package body Prj.Proc is
if The_Array_Element = No_Array_Element then
Array_Element_Table.Increment_Last
(In_Tree.Array_Elements);
- The_Array_Element := Array_Element_Table.Last
- (In_Tree.Array_Elements);
+ The_Array_Element :=
+ Array_Element_Table.Last
+ (In_Tree.Array_Elements);
In_Tree.Array_Elements.Table
(The_Array_Element) :=
- (Index => Index_Name,
- Src_Index =>
- Source_Index_Of
- (Current_Item, From_Project_Node_Tree),
+ (Index => Index_Name,
+ Src_Index => Source_Index,
Index_Case_Sensitive =>
not Case_Insensitive
(Current_Item, From_Project_Node_Tree),
- Value => New_Value,
- Next => In_Tree.Arrays.Table
- (The_Array).Value);
- In_Tree.Arrays.Table
- (The_Array).Value := The_Array_Element;
+ Value => New_Value,
+ Next =>
+ In_Tree.Arrays.Table (The_Array).Value);
+
+ In_Tree.Arrays.Table (The_Array).Value :=
+ The_Array_Element;
-- An element with the same index already exists,
-- just replace its value with the new one.
diff --git a/gcc/ada/prj-tree.adb b/gcc/ada/prj-tree.adb
index df6e5acb6cf..be8f5fcfeda 100644
--- a/gcc/ada/prj-tree.adb
+++ b/gcc/ada/prj-tree.adb
@@ -2966,12 +2966,17 @@ package body Prj.Tree is
(Node : Project_Node_Id;
Tree : Project_Node_Tree_Ref) return Project_Node_Id
is
- Expr : constant Project_Node_Id :=
- Default_Project_Node (Tree, N_Expression, Single);
- begin
- Set_First_Term (Expr, Tree, Default_Project_Node (Tree, N_Term, Single));
- Set_Current_Term (First_Term (Expr, Tree), Tree, Node);
- return Expr;
+ Expr : Project_Node_Id;
+ begin
+ if Kind_Of (Node, Tree) /= N_Expression then
+ Expr := Default_Project_Node (Tree, N_Expression, Single);
+ Set_First_Term
+ (Expr, Tree, Default_Project_Node (Tree, N_Term, Single));
+ Set_Current_Term (First_Term (Expr, Tree), Tree, Node);
+ return Expr;
+ else
+ return Node;
+ end if;
end Enclose_In_Expression;
--------------------
@@ -3022,7 +3027,7 @@ package body Prj.Tree is
return Pack;
end Create_Package;
- -------------------
+ ----------------------
-- Create_Attribute --
----------------------
@@ -3032,7 +3037,8 @@ package body Prj.Tree is
Name : Name_Id;
Index_Name : Name_Id := No_Name;
Kind : Variable_Kind := List;
- At_Index : Integer := 0) return Project_Node_Id
+ At_Index : Integer := 0;
+ Value : Project_Node_Id := Empty_Node) return Project_Node_Id
is
Node : constant Project_Node_Id :=
Default_Project_Node (Tree, N_Attribute_Declaration, Kind);
@@ -3041,14 +3047,11 @@ package body Prj.Tree is
Pkg : Package_Node_Id;
Start_At : Attribute_Node_Id;
+ Expr : Project_Node_Id;
begin
Set_Name_Of (Node, Tree, Name);
- if At_Index /= 0 then
- Set_Source_Index_Of (Node, Tree, To => Int (At_Index));
- end if;
-
if Index_Name /= No_Name then
Set_Associative_Array_Index_Of (Node, Tree, Index_Name);
end if;
@@ -3073,6 +3076,33 @@ package body Prj.Tree is
Attribute_Kind_Of (Start_At) = Case_Insensitive_Associative_Array;
Tree.Project_Nodes.Table (Node).Flag1 := Case_Insensitive;
+ if At_Index /= 0 then
+ if Attribute_Kind_Of (Start_At) =
+ Optional_Index_Associative_Array
+ or else Attribute_Kind_Of (Start_At) =
+ Optional_Index_Case_Insensitive_Associative_Array
+ then
+ -- Results in: for Name ("index" at index) use "value";
+ -- This is currently only used for executables.
+
+ Set_Source_Index_Of (Node, Tree, To => Int (At_Index));
+
+ else
+ -- Results in: for Name ("index") use "value" at index;
+
+ -- ??? This limitation makes no sense, we should be able to
+ -- set the source index on an expression.
+
+ pragma Assert (Kind_Of (Value, Tree) = N_Literal_String);
+ Set_Source_Index_Of (Value, Tree, To => Int (At_Index));
+ end if;
+ end if;
+
+ if Value /= Empty_Node then
+ Expr := Enclose_In_Expression (Value, Tree);
+ Set_Expression_Of (Node, Tree, Expr);
+ end if;
+
return Node;
end Create_Attribute;
diff --git a/gcc/ada/prj-tree.ads b/gcc/ada/prj-tree.ads
index 96a28279c32..fa8c132e565 100644
--- a/gcc/ada/prj-tree.ads
+++ b/gcc/ada/prj-tree.ads
@@ -408,7 +408,8 @@ package Prj.Tree is
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
pragma Inline (First_Declarative_Item_Of);
- -- Only valid for N_With_Clause nodes
+ -- Only valid for N_Project_Declaration, N_Case_Item and
+ -- N_Package_Declaration.
function Extended_Project_Of
(Node : Project_Node_Id;
@@ -492,7 +493,7 @@ package Prj.Tree is
In_Tree : Project_Node_Tree_Ref) return Name_Id;
pragma Inline (Associative_Array_Index_Of);
-- Only valid for N_Attribute_Declaration and N_Attribute_Reference.
- -- Returns No_String for non associative array attributes.
+ -- Returns No_Name for non associative array attributes.
function Next_Variable
(Node : Project_Node_Id;
@@ -573,8 +574,8 @@ package Prj.Tree is
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref) return Project_Node_Id;
pragma Inline (First_Choice_Of);
- -- Return the first choice in a N_Case_Item, or Empty_Node if
- -- this is when others.
+ -- Only valid for N_Case_Item nodes. Return the first choice in a
+ -- N_Case_Item, or Empty_Node if this is when others.
function Next_Case_Item
(Node : Project_Node_Id;
@@ -613,16 +614,25 @@ package Prj.Tree is
(Tree : Project_Node_Tree_Ref;
Prj_Or_Pkg : Project_Node_Id;
Name : Name_Id;
- Index_Name : Name_Id := No_Name;
- Kind : Variable_Kind := List;
- At_Index : Integer := 0) return Project_Node_Id;
+ Index_Name : Name_Id := No_Name;
+ Kind : Variable_Kind := List;
+ At_Index : Integer := 0;
+ Value : Project_Node_Id := Empty_Node) return Project_Node_Id;
-- Create a new attribute. The new declaration is added at the end of the
-- declarative item list for Prj_Or_Pkg (a project or a package), but
-- before any package declaration). No addition is done if Prj_Or_Pkg is
-- Empty_Node. If Index_Name is not "", then if creates an attribute value
-- for a specific index. At_Index is used for the " at <idx>" in the naming
- -- exceptions. Use Set_Expression_Of to set the value of the attribute (in
- -- which case Enclose_In_Expression might be useful)
+ -- exceptions.
+ --
+ -- To set the value of the attribute, either provide a value for Value, or
+ -- use Set_Expression_Of to set the value of the attribute (in which case
+ -- Enclose_In_Expression might be useful). The former is recommended since
+ -- it will more correctly handle cases where the index needs to be set on
+ -- the expression rather than on the index of the attribute (i.e. 'for
+ -- Specification ("unit") use "file" at 3', versus 'for Executable ("file"
+ -- at 3) use "name"'). Value must be a N_String_Literal if an index will be
+ -- added to it.
function Create_Literal_String
(Str : Namet.Name_Id;
@@ -647,7 +657,8 @@ package Prj.Tree is
function Enclose_In_Expression
(Node : Project_Node_Id;
Tree : Project_Node_Tree_Ref) return Project_Node_Id;
- -- Enclose the Node inside a N_Expression node, and return this expression
+ -- Enclose the Node inside a N_Expression node, and return this expression.
+ -- This does nothing if Node is already a N_Expression.
--------------------
-- Set Procedures --
@@ -656,8 +667,11 @@ package Prj.Tree is
-- The following procedures are part of the abstract interface of the
-- Project File tree.
- -- Each Set_* procedure is valid only for the same Project_Node_Kind
- -- nodes as the corresponding query function above.
+ -- Foe each Set_* procedure the condition of validity is specified. If an
+ -- access function is called with invalid arguments, then exception
+ -- Assertion_Error is raised if assertions are enabled, otherwise the
+ -- behaviour is not defined and may result in a crash.
+
-- These are very low-level, and manipulate the tree itself directly. You
-- should look at the Create_* procedure instead if you want to use higher
-- level constructs
@@ -667,146 +681,183 @@ package Prj.Tree is
In_Tree : Project_Node_Tree_Ref;
To : Name_Id);
pragma Inline (Set_Name_Of);
+ -- Valid for all non empty nodes.
procedure Set_Kind_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Kind);
pragma Inline (Set_Kind_Of);
+ -- Valid for all non empty nodes
procedure Set_Location_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Source_Ptr);
pragma Inline (Set_Location_Of);
+ -- Valid for all non empty nodes
procedure Set_First_Comment_After
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_First_Comment_After);
+ -- Valid only for N_Comment_Zones nodes
procedure Set_First_Comment_After_End
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_First_Comment_After_End);
+ -- Valid only for N_Comment_Zones nodes
procedure Set_First_Comment_Before
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_First_Comment_Before);
+ -- Valid only for N_Comment_Zones nodes
procedure Set_First_Comment_Before_End
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_First_Comment_Before_End);
+ -- Valid only for N_Comment_Zones nodes
procedure Set_Next_Comment
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Next_Comment);
+ -- Valid only for N_Comment nodes
procedure Set_Parent_Project_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
+ -- Valid only for N_Project nodes
procedure Set_Project_File_Includes_Unkept_Comments
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Boolean);
+ -- Valid only for N_Project nodes
procedure Set_Directory_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Path_Name_Type);
pragma Inline (Set_Directory_Of);
+ -- Valid only for N_Project nodes
procedure Set_Expression_Kind_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Variable_Kind);
pragma Inline (Set_Expression_Kind_Of);
+ -- Only valid for N_Literal_String, N_Attribute_Declaration,
+ -- N_Variable_Declaration, N_Typed_Variable_Declaration, N_Expression,
+ -- N_Term, N_Variable_Reference or N_Attribute_Reference nodes.
procedure Set_Is_Extending_All
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref);
pragma Inline (Set_Is_Extending_All);
+ -- Only valid for N_Project and N_With_Clause
procedure Set_Is_Not_Last_In_List
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref);
pragma Inline (Set_Is_Not_Last_In_List);
+ -- Only valid for N_With_Clause
procedure Set_First_Variable_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Variable_Node_Id);
pragma Inline (Set_First_Variable_Of);
+ -- Only valid for N_Project or N_Package_Declaration nodes
procedure Set_First_Package_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Package_Declaration_Id);
pragma Inline (Set_First_Package_Of);
+ -- Only valid for N_Project nodes
procedure Set_Package_Id_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Package_Node_Id);
pragma Inline (Set_Package_Id_Of);
+ -- Only valid for N_Package_Declaration nodes
procedure Set_Path_Name_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Path_Name_Type);
pragma Inline (Set_Path_Name_Of);
+ -- Only valid for N_Project and N_With_Clause nodes
procedure Set_String_Value_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Name_Id);
pragma Inline (Set_String_Value_Of);
+ -- Only valid for N_With_Clause, N_Literal_String nodes or N_Comment.
+
+ procedure Set_Source_Index_Of
+ (Node : Project_Node_Id;
+ In_Tree : Project_Node_Tree_Ref;
+ To : Int);
+ pragma Inline (Set_Source_Index_Of);
+ -- Only valid for N_Literal_String and N_Attribute_Declaration nodes. For
+ -- N_Literal_String, set the source index of the litteral string. For
+ -- N_Attribute_Declaration, set the source index of the index of the
+ -- associative array element.
procedure Set_First_With_Clause_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_First_With_Clause_Of);
+ -- Only valid for N_Project nodes
procedure Set_Project_Declaration_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Project_Declaration_Of);
+ -- Only valid for N_Project nodes
procedure Set_Project_Qualifier_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Qualifier);
pragma Inline (Set_Project_Qualifier_Of);
+ -- Only valid for N_Project nodes
procedure Set_Extending_Project_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Extending_Project_Of);
+ -- Only valid for N_Project_Declaration nodes
procedure Set_First_String_Type_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_First_String_Type_Of);
+ -- Only valid for N_Project nodes
procedure Set_Extended_Project_Path_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Path_Name_Type);
pragma Inline (Set_Extended_Project_Path_Of);
+ -- Only valid for N_With_Clause nodes
procedure Set_Project_Node_Of
(Node : Project_Node_Id;
@@ -814,185 +865,214 @@ package Prj.Tree is
To : Project_Node_Id;
Limited_With : Boolean := False);
pragma Inline (Set_Project_Node_Of);
+ -- Only valid for N_With_Clause, N_Variable_Reference and
+ -- N_Attribute_Reference nodes.
procedure Set_Next_With_Clause_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Next_With_Clause_Of);
+ -- Only valid for N_With_Clause nodes
procedure Set_First_Declarative_Item_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_First_Declarative_Item_Of);
+ -- Only valid for N_Project_Declaration, N_Case_Item and
+ -- N_Package_Declaration.
procedure Set_Extended_Project_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Extended_Project_Of);
+ -- Only valid for N_Project_Declaration nodes
procedure Set_Current_Item_Node
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Current_Item_Node);
+ -- Only valid for N_Declarative_Item nodes
procedure Set_Next_Declarative_Item
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Next_Declarative_Item);
+ -- Only valid for N_Declarative_Item node
procedure Set_Project_Of_Renamed_Package_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Project_Of_Renamed_Package_Of);
+ -- Only valid for N_Package_Declaration nodes.
procedure Set_Next_Package_In_Project
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Next_Package_In_Project);
+ -- Only valid for N_Package_Declaration nodes
procedure Set_First_Literal_String
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_First_Literal_String);
+ -- Only valid for N_String_Type_Declaration nodes
procedure Set_Next_String_Type
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Next_String_Type);
+ -- Only valid for N_String_Type_Declaration nodes
procedure Set_Next_Literal_String
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Next_Literal_String);
+ -- Only valid for N_Literal_String nodes
procedure Set_Expression_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Expression_Of);
+ -- Only valid for N_Attribute_Declaration, N_Typed_Variable_Declaration
+ -- or N_Variable_Declaration nodes
procedure Set_Associative_Project_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Associative_Project_Of);
+ -- Only valid for N_Attribute_Declaration nodes
procedure Set_Associative_Package_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Associative_Package_Of);
+ -- Only valid for N_Attribute_Declaration nodes
procedure Set_Associative_Array_Index_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Name_Id);
pragma Inline (Set_Associative_Array_Index_Of);
+ -- Only valid for N_Attribute_Declaration and N_Attribute_Reference.
procedure Set_Next_Variable
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Next_Variable);
+ -- Only valid for N_Typed_Variable_Declaration or N_Variable_Declaration
+ -- nodes.
procedure Set_First_Term
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_First_Term);
+ -- Only valid for N_Expression nodes
procedure Set_Next_Expression_In_List
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Next_Expression_In_List);
+ -- Only valid for N_Expression nodes
procedure Set_Current_Term
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Current_Term);
+ -- Only valid for N_Term nodes
procedure Set_Next_Term
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Next_Term);
+ -- Only valid for N_Term nodes
procedure Set_First_Expression_In_List
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_First_Expression_In_List);
+ -- Only valid for N_Literal_String_List nodes
procedure Set_Package_Node_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Package_Node_Of);
-
- procedure Set_Source_Index_Of
- (Node : Project_Node_Id;
- In_Tree : Project_Node_Tree_Ref;
- To : Int);
- pragma Inline (Set_Source_Index_Of);
+ -- Only valid for N_Variable_Reference or N_Attribute_Reference nodes.
procedure Set_String_Type_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_String_Type_Of);
+ -- Only valid for N_Variable_Reference or N_Typed_Variable_Declaration
+ -- nodes.
procedure Set_External_Reference_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_External_Reference_Of);
+ -- Only valid for N_External_Value nodes
procedure Set_External_Default_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_External_Default_Of);
+ -- Only valid for N_External_Value nodes
procedure Set_Case_Variable_Reference_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Case_Variable_Reference_Of);
+ -- Only valid for N_Case_Construction nodes
procedure Set_First_Case_Item_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_First_Case_Item_Of);
+ -- Only valid for N_Case_Construction nodes
procedure Set_First_Choice_Of
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_First_Choice_Of);
+ -- Only valid for N_Case_Item nodes.
procedure Set_Next_Case_Item
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Project_Node_Id);
pragma Inline (Set_Next_Case_Item);
+ -- Only valid for N_Case_Item nodes.
procedure Set_Case_Insensitive
(Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref;
To : Boolean);
+ -- Only valid for N_Attribute_Declaration and N_Attribute_Reference nodes
-------------------------------
-- Restricted Access Section --
@@ -1377,8 +1457,8 @@ package Prj.Tree is
Key => Name_Id,
Hash => Hash,
Equal => "=");
- -- General type for htables associating name_id to name_id.
- -- This is in particular used to store the values of external references
+ -- General type for htables associating name_id to name_id. This is in
+ -- particular used to store the values of external references.
type Project_Node_Tree_Data is record
Project_Nodes : Tree_Private_Part.Project_Node_Table.Instance;
diff --git a/gcc/ada/prj.adb b/gcc/ada/prj.adb
index d42e7117cd5..0bae53c23fc 100644
--- a/gcc/ada/prj.adb
+++ b/gcc/ada/prj.adb
@@ -23,9 +23,6 @@
-- --
------------------------------------------------------------------------------
-with Ada.Characters.Handling; use Ada.Characters.Handling;
-with Ada.Unchecked_Deallocation;
-
with Debug;
with Osint; use Osint;
with Output; use Output;
@@ -34,6 +31,9 @@ with Prj.Err; use Prj.Err;
with Snames; use Snames;
with Uintp; use Uintp;
+with Ada.Characters.Handling; use Ada.Characters.Handling;
+with Ada.Unchecked_Deallocation;
+
with GNAT.Directory_Operations; use GNAT.Directory_Operations;
with System.Case_Util; use System.Case_Util;
@@ -86,8 +86,6 @@ package body Prj is
Libgnarl_Needed => Unknown,
Symbol_Data => No_Symbols,
Interfaces_Defined => False,
- Include_Path => null,
- Include_Data_Set => False,
Source_Dirs => Nil_String,
Source_Dir_Ranks => No_Number_List,
Object_Directory => No_Path_Information,
@@ -98,18 +96,18 @@ package body Prj is
Languages => No_Language_Index,
Decl => No_Declarations,
Imported_Projects => null,
+ Include_Path_File => No_Path,
All_Imported_Projects => null,
Ada_Include_Path => null,
- Imported_Directories_Switches => null,
Ada_Objects_Path => null,
Objects_Path => null,
- Include_Path_File => No_Path,
Objects_Path_File_With_Libs => No_Path,
Objects_Path_File_Without_Libs => No_Path,
Config_File_Name => No_Path,
Config_File_Temp => False,
Config_Checked => False,
Need_To_Build_Lib => False,
+ Has_Multi_Unit_Sources => False,
Depth => 0,
Unkept_Comments => False);
@@ -682,6 +680,39 @@ package body Prj is
end if;
end Object_Name;
+ function Object_Name
+ (Source_File_Name : File_Name_Type;
+ Source_Index : Int;
+ Index_Separator : Character;
+ Object_File_Suffix : Name_Id := No_Name) return File_Name_Type
+ is
+ Index_Img : constant String := Source_Index'Img;
+ Last : Natural;
+
+ begin
+ Get_Name_String (Source_File_Name);
+
+ Last := Name_Len;
+ while Last > 1 and then Name_Buffer (Last) /= '.' loop
+ Last := Last - 1;
+ end loop;
+
+ if Last > 1 then
+ Name_Len := Last - 1;
+ end if;
+
+ Add_Char_To_Name_Buffer (Index_Separator);
+ Add_Str_To_Name_Buffer (Index_Img (2 .. Index_Img'Last));
+
+ if Object_File_Suffix = No_Name then
+ Add_Str_To_Name_Buffer (Object_Suffix);
+ else
+ Add_Str_To_Name_Buffer (Get_Name_String (Object_File_Suffix));
+ end if;
+
+ return Name_Find;
+ end Object_Name;
+
----------------------
-- Record_Temp_File --
----------------------
@@ -704,7 +735,6 @@ package body Prj is
begin
if Project /= null then
- Free (Project.Include_Path);
Free (Project.Ada_Include_Path);
Free (Project.Objects_Path);
Free (Project.Ada_Objects_Path);
@@ -1055,7 +1085,8 @@ package body Prj is
-- Compute_All_Imported_Projects --
-----------------------------------
- procedure Compute_All_Imported_Projects (Project : Project_Id) is
+ procedure Compute_All_Imported_Projects (Tree : Project_Tree_Ref) is
+ Project : Project_Id;
procedure Recursive_Add (Prj : Project_Id; Dummy : in out Boolean);
-- Recursively add the projects imported by project Project, but not
@@ -1103,10 +1134,16 @@ package body Prj is
new For_Every_Project_Imported (Boolean, Recursive_Add);
Dummy : Boolean := False;
+ List : Project_List;
begin
- Free_List (Project.All_Imported_Projects, Free_Project => False);
- For_All_Projects (Project, Dummy);
+ List := Tree.Projects;
+ while List /= null loop
+ Project := List.Project;
+ Free_List (Project.All_Imported_Projects, Free_Project => False);
+ For_All_Projects (Project, Dummy);
+ List := List.Next;
+ end loop;
end Compute_All_Imported_Projects;
-------------------
@@ -1207,6 +1244,27 @@ package body Prj is
Require_Obj_Dirs => Require_Obj_Dirs);
end Create_Flags;
+ ------------
+ -- Length --
+ ------------
+
+ function Length
+ (Table : Name_List_Table.Instance;
+ List : Name_List_Index) return Natural
+ is
+ Count : Natural := 0;
+ Tmp : Name_List_Index;
+
+ begin
+ Tmp := List;
+ while Tmp /= No_Name_List loop
+ Count := Count + 1;
+ Tmp := Table.Table (Tmp).Next;
+ end loop;
+
+ return Count;
+ end Length;
+
begin
-- Make sure that the standard config and user project file extensions are
-- compatible with canonical case file naming.
diff --git a/gcc/ada/prj.ads b/gcc/ada/prj.ads
index 453a7ca4d70..7fd97916ad1 100644
--- a/gcc/ada/prj.ads
+++ b/gcc/ada/prj.ads
@@ -31,6 +31,7 @@
with Casing; use Casing;
with Namet; use Namet;
+with Osint;
with Scans; use Scans;
with Types; use Types;
@@ -160,7 +161,7 @@ package Prj is
end case;
end record;
-- Values for variables and array elements. Default is True if the
- -- current value is the default one for the variable
+ -- current value is the default one for the variable.
Nil_Variable_Value : constant Variable_Value;
-- Value of a non existing variable or array element
@@ -278,8 +279,8 @@ package Prj is
function Hash (Name : Name_Id) return Header_Num;
function Hash (Name : File_Name_Type) return Header_Num;
function Hash (Name : Path_Name_Type) return Header_Num;
- function Hash (Project : Project_Id) return Header_Num;
- -- Used for computing hash values for names put into above hash table
+ function Hash (Project : Project_Id) return Header_Num;
+ -- Used for computing hash values for names put into hash tables
type Language_Kind is (File_Based, Unit_Based);
-- Type for the kind of language. All languages are file based, except Ada
@@ -316,6 +317,11 @@ package Prj is
Table_Increment => 100);
-- The table for lists of names
+ function Length
+ (Table : Name_List_Table.Instance;
+ List : Name_List_Index) return Natural;
+ -- Return the number of elements in specified list
+
type Number_List_Index is new Nat;
No_Number_List : constant Number_List_Index := 0;
@@ -341,6 +347,8 @@ package Prj is
Equal => "=");
-- A hash table to store the mapping files that are not used
+ -- The following record ???
+
type Lang_Naming_Data is record
Dot_Replacement : File_Name_Type := No_File;
-- The string to replace '.' in the source file name (for Ada)
@@ -396,10 +404,11 @@ package Prj is
type Path_Syntax_Kind is
(Canonical,
-- Unix style
-
Host);
-- Host specific syntax, for example on VMS (the default)
+ -- The following record describes the configuration of a language
+
type Language_Config is record
Kind : Language_Kind := File_Based;
-- Kind of language. All languages are file based, except Ada which is
@@ -409,10 +418,10 @@ package Prj is
-- The naming data for the languages (prefixes, etc.)
Include_Compatible_Languages : Name_List_Index := No_Name_List;
- -- The list of languages that are "include compatible" with this
- -- language. A language B (for example "C") is "include compatible" with
- -- a language A (for example "C++") if it is expected that sources of
- -- language A may "include" header files from language B.
+ -- List of languages that are "include compatible" with this language. A
+ -- language B (for example "C") is "include compatible" with a language
+ -- A (for example "C++") if it is expected that sources of language A
+ -- may "include" header files from language B.
Compiler_Driver : File_Name_Type := No_File;
-- The name of the executable for the compiler of the language
@@ -428,14 +437,21 @@ package Prj is
-- The list of final switches that are required as a minimum to invoke
-- the compiler driver.
- Path_Syntax : Path_Syntax_Kind := Host;
+ Multi_Unit_Switches : Name_List_Index := No_Name_List;
+ -- The switch(es) to indicate the index of a unit in a multi-source file
+
+ Multi_Unit_Object_Separator : Character := ' ';
+ -- The string separating the base name of a source from the index of the
+ -- unit in a multi-source file, in the object file name.
+
+ Path_Syntax : Path_Syntax_Kind := Host;
-- Value may be Canonical (Unix style) or Host (host syntax, for example
-- on VMS for DEC C).
- Object_File_Suffix : Name_Id := No_Name;
+ Object_File_Suffix : Name_Id := No_Name;
-- Optional alternate object file suffix
- Object_File_Switches : Name_List_Index := No_Name_List;
+ Object_File_Switches : Name_List_Index := No_Name_List;
-- Optional object file switches. When this is defined, the switches
-- are used to specify the object file. The object file name is appended
-- to the last switch in the list. Example: ("-o", "").
@@ -445,48 +461,47 @@ package Prj is
-- shared libraries. Specified in the configuration. When not specified,
-- there is no need for such switch.
- Object_Generated : Boolean := True;
+ Object_Generated : Boolean := True;
-- False in no object file is generated
- Objects_Linked : Boolean := True;
+ Objects_Linked : Boolean := True;
-- False if object files are not use to link executables and build
-- libraries.
- Runtime_Library_Dir : Name_Id := No_Name;
+ Runtime_Library_Dir : Name_Id := No_Name;
-- Path name of the runtime library directory, if any
- Runtime_Source_Dir : Name_Id := No_Name;
+ Runtime_Source_Dir : Name_Id := No_Name;
-- Path name of the runtime source directory, if any
- Mapping_File_Switches : Name_List_Index := No_Name_List;
+ Mapping_File_Switches : Name_List_Index := No_Name_List;
-- The option(s) to provide a mapping file to the compiler. Specified in
-- the configuration. When value is No_Name_List, there is no mapping
-- file.
- Mapping_Spec_Suffix : File_Name_Type := No_File;
+ Mapping_Spec_Suffix : File_Name_Type := No_File;
-- Placeholder representing the spec suffix in a mapping file
- Mapping_Body_Suffix : File_Name_Type := No_File;
+ Mapping_Body_Suffix : File_Name_Type := No_File;
-- Placeholder representing the body suffix in a mapping file
- Config_File_Switches : Name_List_Index := No_Name_List;
+ Config_File_Switches : Name_List_Index := No_Name_List;
-- The option(s) to provide a config file to the compiler. Specified in
- -- the configuration. When value is No_Name_List, there is no config
- -- file.
+ -- the configuration. If value is No_Name_List there is no config file.
- Dependency_Kind : Dependency_File_Kind := None;
+ Dependency_Kind : Dependency_File_Kind := None;
-- The kind of dependency to be checked: none, Makefile fragment or
-- ALI file (for Ada).
- Dependency_Option : Name_List_Index := No_Name_List;
+ Dependency_Option : Name_List_Index := No_Name_List;
-- The option(s) to be used to create the dependency file. When value is
-- No_Name_List, there is not such option(s).
- Compute_Dependency : Name_List_Index := No_Name_List;
+ Compute_Dependency : Name_List_Index := No_Name_List;
-- Hold the value of attribute Dependency_Driver, if declared for the
-- language.
- Include_Option : Name_List_Index := No_Name_List;
+ Include_Option : Name_List_Index := No_Name_List;
-- Hold the value of attribute Include_Switches, if declared for the
-- language.
@@ -506,47 +521,54 @@ package Prj is
-- Name of environment variable declared by attribute Objects_Path_File
-- for the language.
- Config_Body : Name_Id := No_Name;
+ Config_Body : Name_Id := No_Name;
-- The template for a pragma Source_File_Name(_Project) for a specific
-- file name of a body.
- Config_Spec : Name_Id := No_Name;
+ Config_Body_Index : Name_Id := No_Name;
-- The template for a pragma Source_File_Name(_Project) for a specific
- -- file name of a spec.
+ -- file name of a body in a multi-source file.
- Config_Body_Pattern : Name_Id := No_Name;
+ Config_Body_Pattern : Name_Id := No_Name;
-- The template for a pragma Source_File_Name(_Project) for a naming
-- body pattern.
- Config_Spec_Pattern : Name_Id := No_Name;
+ Config_Spec : Name_Id := No_Name;
+ -- The template for a pragma Source_File_Name(_Project) for a specific
+ -- file name of a spec.
+
+ Config_Spec_Index : Name_Id := No_Name;
+ -- The template for a pragma Source_File_Name(_Project) for a specific
+ -- file name of a spec in a multi-source file.
+
+ Config_Spec_Pattern : Name_Id := No_Name;
-- The template for a pragma Source_File_Name(_Project) for a naming
-- spec pattern.
- Config_File_Unique : Boolean := False;
+ Config_File_Unique : Boolean := False;
-- Indicate if the config file specified to the compiler needs to be
-- unique. If it is unique, then all config files are concatenated into
-- a temp config file.
- Binder_Driver : File_Name_Type := No_File;
+ Binder_Driver : File_Name_Type := No_File;
-- The name of the binder driver for the language, if any
- Binder_Driver_Path : Path_Name_Type := No_Path;
+ Binder_Driver_Path : Path_Name_Type := No_Path;
-- The path name of the binder driver
- Binder_Required_Switches : Name_List_Index := No_Name_List;
+ Binder_Required_Switches : Name_List_Index := No_Name_List;
-- Hold the value of attribute Binder'Required_Switches for the language
- Binder_Prefix : Name_Id := No_Name;
+ Binder_Prefix : Name_Id := No_Name;
-- Hold the value of attribute Binder'Prefix for the language
- Toolchain_Version : Name_Id := No_Name;
+ Toolchain_Version : Name_Id := No_Name;
-- Hold the value of attribute Toolchain_Version for the language
- Toolchain_Description : Name_Id := No_Name;
+ Toolchain_Description : Name_Id := No_Name;
-- Hold the value of attribute Toolchain_Description for the language
end record;
- -- Record describing the configuration of a language
No_Language_Config : constant Language_Config :=
(Kind => File_Based,
@@ -556,6 +578,8 @@ package Prj is
Compiler_Driver_Path => null,
Compiler_Leading_Required_Switches => No_Name_List,
Compiler_Trailing_Required_Switches => No_Name_List,
+ Multi_Unit_Switches => No_Name_List,
+ Multi_Unit_Object_Separator => ' ',
Path_Syntax => Canonical,
Object_File_Suffix => No_Name,
Object_File_Switches => No_Name_List,
@@ -577,8 +601,10 @@ package Prj is
Objects_Path => No_Name,
Objects_Path_File => No_Name,
Config_Body => No_Name,
- Config_Spec => No_Name,
+ Config_Body_Index => No_Name,
Config_Body_Pattern => No_Name,
+ Config_Spec => No_Name,
+ Config_Spec_Index => No_Name,
Config_Spec_Pattern => No_Name,
Config_File_Unique => False,
Binder_Driver => No_File,
@@ -588,6 +614,8 @@ package Prj is
Toolchain_Version => No_Name,
Toolchain_Description => No_Name);
+ -- The following record ???
+
type Language_Data is record
Name : Name_Id := No_Name;
Display_Name : Name_Id := No_Name;
@@ -636,104 +664,105 @@ package Prj is
-- Structure to define source data
type Source_Data is record
- Project : Project_Id := No_Project;
+ Project : Project_Id := No_Project;
-- Project of the source
- Source_Dir_Rank : Natural := 0;
+ Source_Dir_Rank : Natural := 0;
-- The rank of the source directory in list declared with attribute
-- Source_Dirs. Two source files with the same name cannot appears in
-- different directory with the same rank. That can happen when the
-- recursive notation <dir>/** is used in attribute Source_Dirs.
- Language : Language_Ptr := No_Language_Index;
+ Language : Language_Ptr := No_Language_Index;
-- Index of the language. This is an index into
-- Project_Tree.Languages_Data.
- In_Interfaces : Boolean := True;
+ In_Interfaces : Boolean := True;
-- False when the source is not included in interfaces, when attribute
-- Interfaces is declared.
- Declared_In_Interfaces : Boolean := False;
+ Declared_In_Interfaces : Boolean := False;
-- True when source is declared in attribute Interfaces
- Alternate_Languages : Language_List := null;
+ Alternate_Languages : Language_List := null;
-- List of languages a header file may also be, in addition of language
-- Language_Name.
- Kind : Source_Kind := Spec;
+ Kind : Source_Kind := Spec;
-- Kind of the source: spec, body or subunit
- Unit : Unit_Index := No_Unit_Index;
+ Unit : Unit_Index := No_Unit_Index;
-- Name of the unit, if language is unit based. This is only set for
-- those files that are part of the compilation set (for instance a
-- file in an extended project that is overridden will not have this
-- field set).
- Index : Int := 0;
+ Index : Int := 0;
-- Index of the source in a multi unit source file (the same Source_Data
-- is duplicated several times when there are several units in the same
-- file). Index is 0 if there is either no unit or a single one, and
-- starts at 1 when there are multiple units
- Locally_Removed : Boolean := False;
+ Locally_Removed : Boolean := False;
-- True if the source has been "excluded"
- Replaced_By : Source_Id := No_Source;
+ Replaced_By : Source_Id := No_Source;
+ -- Missing comment ???
- File : File_Name_Type := No_File;
+ File : File_Name_Type := No_File;
-- Canonical file name of the source
- Display_File : File_Name_Type := No_File;
+ Display_File : File_Name_Type := No_File;
-- File name of the source, for display purposes
- Path : Path_Information := No_Path_Information;
+ Path : Path_Information := No_Path_Information;
-- Path name of the source
- Source_TS : Time_Stamp_Type := Empty_Time_Stamp;
+ Source_TS : Time_Stamp_Type := Empty_Time_Stamp;
-- Time stamp of the source file
- Object_Project : Project_Id := No_Project;
+ Object_Project : Project_Id := No_Project;
-- Project where the object file is. This might be different from
-- Project when using extending project files.
- Object : File_Name_Type := No_File;
+ Object : File_Name_Type := No_File;
-- File name of the object file
- Current_Object_Path : Path_Name_Type := No_Path;
+ Current_Object_Path : Path_Name_Type := No_Path;
-- Object path of an existing object file
- Object_Path : Path_Name_Type := No_Path;
+ Object_Path : Path_Name_Type := No_Path;
-- Object path of the real object file
- Object_TS : Time_Stamp_Type := Empty_Time_Stamp;
+ Object_TS : Time_Stamp_Type := Empty_Time_Stamp;
-- Object file time stamp
- Dep_Name : File_Name_Type := No_File;
+ Dep_Name : File_Name_Type := No_File;
-- Dependency file simple name
- Current_Dep_Path : Path_Name_Type := No_Path;
+ Current_Dep_Path : Path_Name_Type := No_Path;
-- Path name of an existing dependency file
- Dep_Path : Path_Name_Type := No_Path;
+ Dep_Path : Path_Name_Type := No_Path;
-- Path name of the real dependency file
- Dep_TS : Time_Stamp_Type := Empty_Time_Stamp;
+ Dep_TS : aliased Osint.File_Attributes := Osint.Unknown_Attributes;
-- Dependency file time stamp
- Switches : File_Name_Type := No_File;
+ Switches : File_Name_Type := No_File;
-- File name of the switches file. For all languages, this is a file
-- that ends with the .cswi extension.
- Switches_Path : Path_Name_Type := No_Path;
+ Switches_Path : Path_Name_Type := No_Path;
-- Path name of the switches file
- Switches_TS : Time_Stamp_Type := Empty_Time_Stamp;
+ Switches_TS : Time_Stamp_Type := Empty_Time_Stamp;
-- Switches file time stamp
- Naming_Exception : Boolean := False;
+ Naming_Exception : Boolean := False;
-- True if the source has an exceptional name
- Next_In_Lang : Source_Id := No_Source;
+ Next_In_Lang : Source_Id := No_Source;
-- Link to another source of the same language in the same project
end record;
@@ -761,7 +790,7 @@ package Prj is
Dep_Name => No_File,
Current_Dep_Path => No_Path,
Dep_Path => No_Path,
- Dep_TS => Empty_Time_Stamp,
+ Dep_TS => Osint.Unknown_Attributes,
Switches => No_File,
Switches_Path => No_Path,
Switches_TS => Empty_Time_Stamp,
@@ -839,9 +868,10 @@ package Prj is
-- If Only_If_Ada is True, then No_Name will be returned when the project
-- doesn't Ada sources.
- procedure Compute_All_Imported_Projects (Project : Project_Id);
- -- Compute, the list of the projects imported directly or indirectly by
- -- project Project. The result is stored in Project.All_Imported_Projects
+ procedure Compute_All_Imported_Projects (Tree : Project_Tree_Ref);
+ -- For all projects in the tree, compute the list of the projects imported
+ -- directly or indirectly by project Project. The result is stored in
+ -- Project.All_Imported_Projects for each project
function Ultimate_Extending_Project_Of
(Proj : Project_Id) return Project_Id;
@@ -869,117 +899,117 @@ package Prj is
-- The format of the different response files
type Project_Configuration is record
- Target : Name_Id := No_Name;
+ Target : Name_Id := No_Name;
-- The target of the configuration, when specified
- Run_Path_Option : Name_List_Index := No_Name_List;
+ Run_Path_Option : Name_List_Index := No_Name_List;
-- The option to use when linking to specify the path where to look for
-- libraries.
- Separate_Run_Path_Options : Boolean := False;
+ Separate_Run_Path_Options : Boolean := False;
-- True if each directory needs to be specified in a separate run path
-- option.
- Executable_Suffix : Name_Id := No_Name;
+ Executable_Suffix : Name_Id := No_Name;
-- The suffix of executables, when specified in the configuration or in
-- package Builder of the main project. When this is not specified, the
-- executable suffix is the default for the platform.
-- Linking
- Linker : Path_Name_Type := No_Path;
+ Linker : Path_Name_Type := No_Path;
-- Path name of the linker driver. Specified in the configuration or in
-- the package Builder of the main project.
- Map_File_Option : Name_Id := No_Name;
+ Map_File_Option : Name_Id := No_Name;
-- Option to use when invoking the linker to build a map file
- Minimum_Linker_Options : Name_List_Index := No_Name_List;
+ Minimum_Linker_Options : Name_List_Index := No_Name_List;
-- The minimum options for the linker driver. Specified in the
-- configuration.
- Linker_Executable_Option : Name_List_Index := No_Name_List;
+ Linker_Executable_Option : Name_List_Index := No_Name_List;
-- The option(s) to indicate the name of the executable in the linker
-- command. Specified in the configuration. When not specified, default
-- to -o <executable name>.
- Linker_Lib_Dir_Option : Name_Id := No_Name;
+ Linker_Lib_Dir_Option : Name_Id := No_Name;
-- The option to specify where to find a library for linking. Specified
-- in the configuration. When not specified, defaults to "-L".
- Linker_Lib_Name_Option : Name_Id := No_Name;
+ Linker_Lib_Name_Option : Name_Id := No_Name;
-- The option to specify the name of a library for linking. Specified in
-- the configuration. When not specified, defaults to "-l".
- Max_Command_Line_Length : Natural := 0;
+ Max_Command_Line_Length : Natural := 0;
-- When positive and when Resp_File_Format (see below) is not None,
-- if the command line for the invocation of the linker would be greater
-- than this value, a response file is used to invoke the linker.
- Resp_File_Format : Response_File_Format := None;
+ Resp_File_Format : Response_File_Format := None;
-- The format of a response file, when linking with a response file is
-- supported.
- Resp_File_Options : Name_List_Index := No_Name_List;
+ Resp_File_Options : Name_List_Index := No_Name_List;
-- The switches, if any, that precede the path name of the response
-- file in the invocation of the linker.
-- Libraries
- Library_Builder : Path_Name_Type := No_Path;
+ Library_Builder : Path_Name_Type := No_Path;
-- The executable to build library (specified in the configuration)
- Lib_Support : Library_Support := None;
+ Lib_Support : Library_Support := None;
-- The level of library support. Specified in the configuration. Support
-- is none, static libraries only or both static and shared libraries.
- Archive_Builder : Name_List_Index := No_Name_List;
+ Archive_Builder : Name_List_Index := No_Name_List;
-- The name of the executable to build archives, with the minimum
-- switches. Specified in the configuration.
Archive_Builder_Append_Option : Name_List_Index := No_Name_List;
-- The options to append object files to an archive
- Archive_Indexer : Name_List_Index := No_Name_List;
+ Archive_Indexer : Name_List_Index := No_Name_List;
-- The name of the executable to index archives, with the minimum
-- switches. Specified in the configuration.
- Archive_Suffix : File_Name_Type := No_File;
+ Archive_Suffix : File_Name_Type := No_File;
-- The suffix of archives. Specified in the configuration. When not
-- specified, defaults to ".a".
- Lib_Partial_Linker : Name_List_Index := No_Name_List;
+ Lib_Partial_Linker : Name_List_Index := No_Name_List;
-- Shared libraries
- Shared_Lib_Driver : File_Name_Type := No_File;
+ Shared_Lib_Driver : File_Name_Type := No_File;
-- The driver to link shared libraries. Set with attribute Library_GCC.
-- Default to gcc.
- Shared_Lib_Prefix : File_Name_Type := No_File;
+ Shared_Lib_Prefix : File_Name_Type := No_File;
-- Part of a shared library file name that precedes the name of the
-- library. Specified in the configuration. When not specified, defaults
-- to "lib".
- Shared_Lib_Suffix : File_Name_Type := No_File;
+ Shared_Lib_Suffix : File_Name_Type := No_File;
-- Suffix of shared libraries, after the library name in the shared
-- library name. Specified in the configuration. When not specified,
-- default to ".so".
- Shared_Lib_Min_Options : Name_List_Index := No_Name_List;
+ Shared_Lib_Min_Options : Name_List_Index := No_Name_List;
-- The minimum options to use when building a shared library
- Lib_Version_Options : Name_List_Index := No_Name_List;
+ Lib_Version_Options : Name_List_Index := No_Name_List;
-- The options to use to specify a library version
- Symbolic_Link_Supported : Boolean := False;
+ Symbolic_Link_Supported : Boolean := False;
-- True if the platform supports symbolic link files
- Lib_Maj_Min_Id_Supported : Boolean := False;
+ Lib_Maj_Min_Id_Supported : Boolean := False;
-- True if platform supports library major and minor options, such as
-- libname.so -> libname.so.2 -> libname.so.2.4
- Auto_Init_Supported : Boolean := False;
+ Auto_Init_Supported : Boolean := False;
-- True if automatic initialisation is supported for shared stand-alone
-- libraries.
end record;
@@ -1159,21 +1189,13 @@ package Prj is
-- The sources for all languages including Ada are accessible through
-- the Source_Iterator type
- Interfaces_Defined : Boolean := False;
+ Interfaces_Defined : Boolean := False;
-- True if attribute Interfaces is declared for the project or any
-- project it extends.
- Include_Path : String_Access := null;
- -- The search source path for the project. Used as the value for an
- -- environment variable, specified by attribute Include_Path
- -- (<language>). The names of the environment variables are in component
- -- Include_Path of the records Language_Config.
-
Include_Path_File : Path_Name_Type := No_Path;
- -- The path name of the of the source search directory file
-
- Include_Data_Set : Boolean := False;
- -- Set True when Imported_Directories_Switches or Include_Path are set
+ -- The path name of the of the source search directory file.
+ -- This is only used by gnatmake
Source_Dirs : String_List_Id := Nil_String;
-- The list of all the source directories
@@ -1186,14 +1208,13 @@ package Prj is
-- use this field directly outside of the project manager, use
-- Prj.Env.Ada_Include_Path instead.
+ Has_Multi_Unit_Sources : Boolean := False;
+ -- Whether there is at least one source file containing multiple units
+
-------------------
-- Miscellaneous --
-------------------
- Imported_Directories_Switches : Argument_List_Access := null;
- -- List of the source search switches (-I<source dir>) to be used
- -- when compiling.
-
Ada_Objects_Path : String_Access := null;
-- The cached value of ADA_OBJECTS_PATH for this project file. Do not
-- use this field directly outside of the compiler, use
@@ -1368,6 +1389,14 @@ package Prj is
Object_File_Suffix : Name_Id := No_Name) return File_Name_Type;
-- Returns the object file name corresponding to a source file name
+ function Object_Name
+ (Source_File_Name : File_Name_Type;
+ Source_Index : Int;
+ Index_Separator : Character;
+ Object_File_Suffix : Name_Id := No_Name) return File_Name_Type;
+ -- Returns the object file name corresponding to a unit in a multi-source
+ -- file.
+
function Dependency_Name
(Source_File_Name : File_Name_Type;
Dependency : Dependency_File_Kind) return File_Name_Type;
diff --git a/gcc/ada/put_scos.adb b/gcc/ada/put_scos.adb
index d7667b85f32..bca3f698815 100644
--- a/gcc/ada/put_scos.adb
+++ b/gcc/ada/put_scos.adb
@@ -37,21 +37,26 @@ begin
Stop : Nat;
begin
- Write_Info_Initiate ('C');
- Write_Info_Char (' ');
- Write_Info_Nat (SUT.Dep_Num);
- Write_Info_Char (' ');
+ Start := SUT.From;
+ Stop := SUT.To;
- for N in SUT.File_Name'Range loop
- Write_Info_Char (SUT.File_Name (N));
- end loop;
+ -- Write unit header (omitted if no SCOs are generated for this unit)
+
+ if Start <= Stop then
+ Write_Info_Initiate ('C');
+ Write_Info_Char (' ');
+ Write_Info_Nat (SUT.Dep_Num);
+ Write_Info_Char (' ');
- Write_Info_Terminate;
+ for N in SUT.File_Name'Range loop
+ Write_Info_Char (SUT.File_Name (N));
+ end loop;
+
+ Write_Info_Terminate;
+ end if;
-- Loop through SCO entries for this unit
- Start := SUT.From;
- Stop := SUT.To;
loop
exit when Start = Stop + 1;
pragma Assert (Start <= Stop);
diff --git a/gcc/ada/s-bitops.adb b/gcc/ada/s-bitops.adb
index a49ffed7b88..c49b829763d 100644
--- a/gcc/ada/s-bitops.adb
+++ b/gcc/ada/s-bitops.adb
@@ -29,6 +29,8 @@
-- --
------------------------------------------------------------------------------
+pragma Compiler_Unit;
+
with System; use System;
with System.Unsigned_Types; use System.Unsigned_Types;
diff --git a/gcc/ada/s-crtl.ads b/gcc/ada/s-crtl.ads
index f013a418fcb..7d5f1107add 100644
--- a/gcc/ada/s-crtl.ads
+++ b/gcc/ada/s-crtl.ads
@@ -29,8 +29,9 @@
-- --
------------------------------------------------------------------------------
--- This package provides the low level interface to the C Run Time Library
--- on non-VMS systems.
+-- This package provides the low level interface to the C runtime library
+
+pragma Compiler_Unit;
with System.Parameters;
@@ -39,6 +40,9 @@ package System.CRTL is
subtype chars is System.Address;
-- Pointer to null-terminated array of characters
+ -- Should use Interfaces.C.Strings types instead, but this causes bootstrap
+ -- issues as i-c contains Ada 2005 specific features, not compatible with
+ -- older, Ada 95-only base compilers???
subtype DIRs is System.Address;
-- Corresponds to the C type DIR*
@@ -49,7 +53,7 @@ package System.CRTL is
subtype int is Integer;
type long is range -(2 ** (System.Parameters.long_bits - 1))
- .. +(2 ** (System.Parameters.long_bits - 1)) - 1;
+ .. +(2 ** (System.Parameters.long_bits - 1)) - 1;
subtype off_t is Long_Integer;
@@ -112,8 +116,7 @@ package System.CRTL is
function fseek
(stream : FILEs;
offset : long;
- origin : int)
- return int;
+ origin : int) return int;
pragma Import (C, fseek, "fseek");
function ftell (stream : FILEs) return long;
@@ -131,11 +134,6 @@ package System.CRTL is
function malloc (Size : size_t) return System.Address;
pragma Import (C, malloc, "malloc");
- function malloc32 (Size : size_t) return System.Address;
- pragma Import (C, malloc32, "malloc");
- -- An uncalled alias for malloc except on 64bit systems needing to
- -- allocate 32bit memory.
-
procedure memcpy (S1 : System.Address; S2 : System.Address; N : size_t);
pragma Import (C, memcpy, "memcpy");
@@ -155,12 +153,6 @@ package System.CRTL is
(Ptr : System.Address; Size : size_t) return System.Address;
pragma Import (C, realloc, "realloc");
- function realloc32
- (Ptr : System.Address; Size : size_t) return System.Address;
- pragma Import (C, realloc32, "realloc");
- -- An uncalled alias for realloc except on 64bit systems needing to
- -- allocate 32bit memory.
-
procedure rewind (stream : FILEs);
pragma Import (C, rewind, "rewind");
@@ -174,8 +166,7 @@ package System.CRTL is
(stream : FILEs;
buffer : chars;
mode : int;
- size : size_t)
- return int;
+ size : size_t) return int;
pragma Import (C, setvbuf, "setvbuf");
procedure tmpnam (string : chars);
@@ -202,7 +193,4 @@ package System.CRTL is
function write (fd : int; buffer : chars; nbytes : int) return int;
pragma Import (C, write, "write");
- function strerror (errno : int) return chars;
- pragma Import (C, strerror, "strerror");
-
end System.CRTL;
diff --git a/gcc/ada/s-errrep.adb b/gcc/ada/s-errrep.adb
deleted file mode 100644
index 783f845d1e4..00000000000
--- a/gcc/ada/s-errrep.adb
+++ /dev/null
@@ -1,68 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
--- --
--- S Y S T E M . E R R O R _ R E P O R T I N G --
--- --
--- B o d y --
--- --
--- Copyright (C) 1995-2006, AdaCore --
--- --
--- GNARL is free software; you can redistribute it and/or modify it under --
--- terms of the GNU General Public License as published by the Free Soft- --
--- ware Foundation; either version 2, or (at your option) any later ver- --
--- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
--- OUT 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 distributed with GNARL; see file COPYING. If not, write --
--- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
--- Boston, MA 02110-1301, USA. --
--- --
--- As a special exception, if other files instantiate generics from this --
--- unit, or you link this unit with other files to produce an executable, --
--- this unit does not by itself cause the resulting executable to be --
--- covered by the GNU General Public License. This exception does not --
--- however invalidate any other reasons why the executable file might be --
--- covered by the GNU Public License. --
--- --
--- GNARL was developed by the GNARL team at Florida State University. --
--- Extensive contributions were provided by Ada Core Technologies, Inc. --
--- --
-------------------------------------------------------------------------------
-
--- This package must not depend on anything else, since it may be
--- called during elaboration of other packages.
-
-package body System.Error_Reporting is
-
- procedure Write (fildes : Integer; buf : System.Address; nbyte : Integer);
- pragma Import (C, Write, "write");
-
- procedure Prog_Exit (Status : Integer);
- pragma No_Return (Prog_Exit);
- pragma Import (C, Prog_Exit, "exit");
-
- Shutdown_Message : String := "failed run-time assertion : ";
- End_Of_Line : String := "" & ASCII.LF;
-
- --------------
- -- Shutdown --
- --------------
-
- function Shutdown (M : String) return Boolean is
- begin
- Write (2, Shutdown_Message'Address, Shutdown_Message'Length);
- Write (2, M'Address, M'Length);
- Write (2, End_Of_Line'Address, End_Of_Line'Length);
-
- -- This call should never return
-
- Prog_Exit (1);
-
- -- Return is just to keep Ada happy (return required)
-
- return False;
- end Shutdown;
-
-end System.Error_Reporting;
diff --git a/gcc/ada/s-errrep.ads b/gcc/ada/s-errrep.ads
deleted file mode 100644
index 930e0206419..00000000000
--- a/gcc/ada/s-errrep.ads
+++ /dev/null
@@ -1,45 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
--- --
--- S Y S T E M . E R R O R _ R E P O R T I N G --
--- --
--- S p e c --
--- --
--- Copyright (C) 1995-2006, AdaCore --
--- --
--- GNARL is free software; you can redistribute it and/or modify it under --
--- terms of the GNU General Public License as published by the Free Soft- --
--- ware Foundation; either version 2, or (at your option) any later ver- --
--- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
--- OUT 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 distributed with GNARL; see file COPYING. If not, write --
--- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
--- Boston, MA 02110-1301, USA. --
--- --
--- As a special exception, if other files instantiate generics from this --
--- unit, or you link this unit with other files to produce an executable, --
--- this unit does not by itself cause the resulting executable to be --
--- covered by the GNU General Public License. This exception does not --
--- however invalidate any other reasons why the executable file might be --
--- covered by the GNU Public License. --
--- --
--- GNARL was developed by the GNARL team at Florida State University. --
--- Extensive contributions were provided by Ada Core Technologies, Inc. --
--- --
-------------------------------------------------------------------------------
-
--- This package must not depend on anything else, since it may be
--- called during elaboration of other packages.
-
-package System.Error_Reporting is
- pragma Preelaborate;
-
- function Shutdown (M : String) return Boolean;
- -- Perform emergency shutdown of the entire program. Msg is an error
- -- message to be printed to the console. This is to be used only for
- -- nonrecoverable errors.
-
-end System.Error_Reporting;
diff --git a/gcc/ada/s-fatgen.adb b/gcc/ada/s-fatgen.adb
index 0db154db4ae..cf7e4254b66 100644
--- a/gcc/ada/s-fatgen.adb
+++ b/gcc/ada/s-fatgen.adb
@@ -232,12 +232,7 @@ package body System.Fat_Gen is
end loop;
end if;
- if X > 0.0 then
- Frac := Ax;
- else
- Frac := -Ax;
- end if;
-
+ Frac := (if X > 0.0 then Ax else -Ax);
Expo := Ex;
end;
end if;
diff --git a/gcc/ada/s-fileio.adb b/gcc/ada/s-fileio.adb
index f93fee25e33..60a96e427cf 100644
--- a/gcc/ada/s-fileio.adb
+++ b/gcc/ada/s-fileio.adb
@@ -31,13 +31,12 @@
with Ada.Finalization; use Ada.Finalization;
with Ada.IO_Exceptions; use Ada.IO_Exceptions;
-with Ada.Unchecked_Conversion;
with Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;
with Interfaces.C_Streams; use Interfaces.C_Streams;
-with System.CRTL;
+with System.CRTL.Runtime;
with System.Case_Util; use System.Case_Util;
with System.OS_Lib;
with System.Soft_Links;
@@ -375,16 +374,7 @@ package body System.File_IO is
-------------------
function Errno_Message (Errno : Integer := OS_Lib.Errno) return String is
- pragma Warnings (Off);
- function To_Chars_Ptr is
- new Ada.Unchecked_Conversion (System.Address, chars_ptr);
- -- On VMS, the compiler warns because System.Address is 64 bits, but
- -- chars_ptr is 32 bits. It should be safe, though, because strerror
- -- will return a 32-bit pointer.
- pragma Warnings (On);
-
- Message : constant chars_ptr :=
- To_Chars_Ptr (CRTL.strerror (Errno));
+ Message : constant chars_ptr := CRTL.Runtime.strerror (Errno);
begin
if Message = Null_Ptr then
@@ -529,27 +519,17 @@ package body System.File_IO is
end if;
when Inout_File | Append_File =>
- if Creat then
- Fopstr (1) := 'w';
- else
- Fopstr (1) := 'r';
- end if;
-
+ Fopstr (1) := (if Creat then 'w' else 'r');
Fopstr (2) := '+';
Fptr := 3;
end case;
- -- If text_translation_required is true then we need to append
- -- either a t or b to the string to get the right mode
+ -- If text_translation_required is true then we need to append either a
+ -- "t" or "b" to the string to get the right mode.
if text_translation_required then
- if Text then
- Fopstr (Fptr) := 't';
- else
- Fopstr (Fptr) := 'b';
- end if;
-
+ Fopstr (Fptr) := (if Text then 't' else 'b');
Fptr := Fptr + 1;
end if;
diff --git a/gcc/ada/s-imgcha.adb b/gcc/ada/s-imgcha.adb
index dd3b4d90eaf..7678bf7205a 100644
--- a/gcc/ada/s-imgcha.adb
+++ b/gcc/ada/s-imgcha.adb
@@ -124,22 +124,13 @@ package body System.Img_Char is
if V in C0_Range then
S (1 .. 3) := C0 (V);
-
- if S (3) = ' ' then
- P := 2;
- else
- P := 3;
- end if;
+ P := (if S (3) = ' ' then 2 else 3);
elsif V in C1_Range then
S (1 .. 3) := C1 (V);
if S (1) /= 'r' then
- if S (3) = ' ' then
- P := 2;
- else
- P := 3;
- end if;
+ P := (if S (3) = ' ' then 2 else 3);
-- Special case, res means RESERVED_nnn where nnn is the three digit
-- decimal value corresponding to the code position (more efficient
diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c
index 48938d9d9d1..1e8bd520ceb 100644
--- a/gcc/ada/s-oscons-tmplt.c
+++ b/gcc/ada/s-oscons-tmplt.c
@@ -84,12 +84,14 @@ pragma Style_Checks ("M32766");
#define _XOPEN_SOURCE 500
#elif defined (__mips) && defined (__sgi)
-/** For IRIX _XOPEN5 must be defined and _XOPEN_IOV_MAX must be used as IOV_MAX,
- ** otherwise IOV_MAX is not defined.
+/** For IRIX 6, _XOPEN5 must be defined and _XOPEN_IOV_MAX must be used as
+ ** IOV_MAX, otherwise IOV_MAX is not defined. IRIX 5 has neither.
**/
+#ifdef _XOPEN_IOV_MAX
#define _XOPEN5
#define IOV_MAX _XOPEN_IOV_MAX
#endif
+#endif
#include <stdlib.h>
#include <string.h>
@@ -161,6 +163,9 @@ int counter = 0;
#define CNS(name,comment) \
printf ("\n->CNS:$%d:" #name ":" name ":" comment, __LINE__);
+#define C(sname,type,value,comment)\
+ printf ("\n->C:$%d:" sname ":" #type ":" value ":" comment, __LINE__);
+
#define TXT(text) \
printf ("\n->TXT:$%d:" text, __LINE__);
@@ -174,7 +179,12 @@ int counter = 0;
#define CNS(name, comment) \
asm volatile("\n->CNS:%0:" #name ":" name ":" comment \
: : "i" (__LINE__));
-/* General expression constant */
+/* General expression named number */
+
+#define C(sname, type, value, comment) \
+ asm volatile("\n->C:%0:" sname ":" #type ":" value ":" comment \
+ : : "i" (__LINE__));
+/* Typed constant */
#define TXT(text) \
asm volatile("\n->TXT:%0:" text \
@@ -183,6 +193,8 @@ int counter = 0;
#endif
+#define CST(name,comment) C(#name,String,name,comment)
+
#define STR(x) STR1(x)
#define STR1(x) #x
@@ -233,10 +245,7 @@ package System.OS_Constants is
-- Platform identification --
-----------------------------
-*/
-TXT(" Target_Name : constant String := " STR(TARGET) ";")
-/*
- type Target_OS_Type is (Windows, VMS, Other_OS);
+ type OS_Type is (Windows, VMS, Other_OS);
*/
#if defined (__MINGW32__)
# define TARGET_OS "Windows"
@@ -245,7 +254,9 @@ TXT(" Target_Name : constant String := " STR(TARGET) ";")
#else
# define TARGET_OS "Other_OS"
#endif
-TXT(" Target_OS : constant Target_OS_Type := " TARGET_OS ";")
+C("Target_OS", OS_Type, TARGET_OS, "")
+#define Target_Name TARGET
+CST(Target_Name, "")
/*
-------------------
@@ -1189,7 +1200,7 @@ CND(SIZEOF_tv_usec, "tv_usec")
}
/*
- -- Sizes of protocol specific address types (for sockaddr.sa_len)
+ -- Sizes of various data types
*/
#define SIZEOF_sockaddr_in (sizeof (struct sockaddr_in))
@@ -1201,12 +1212,11 @@ CND(SIZEOF_sockaddr_in, "struct sockaddr_in")
#endif
CND(SIZEOF_sockaddr_in6, "struct sockaddr_in6")
-/*
-
- -- Size of file descriptor sets
-*/
#define SIZEOF_fd_set (sizeof (fd_set))
CND(SIZEOF_fd_set, "fd_set");
+
+#define SIZEOF_struct_servent (sizeof (struct servent))
+CND(SIZEOF_struct_servent, "struct servent");
/*
-- Fields of struct hostent
@@ -1251,7 +1261,7 @@ CND(Has_Sockaddr_Len, "Sockaddr has sa_len field")
** Do not change the format of the line below without also updating the
** MaRTE Makefile.
**/
-TXT(" Thread_Blocking_IO : constant Boolean := True;")
+C("Thread_Blocking_IO", Boolean, "True", "")
/*
-- Set False for contexts where socket i/o are process blocking
@@ -1262,7 +1272,7 @@ TXT(" Thread_Blocking_IO : constant Boolean := True;")
#else
# define Inet_Pton_Linkname "__gnat_inet_pton"
#endif
-TXT(" Inet_Pton_Linkname : constant String := \"" Inet_Pton_Linkname "\";")
+CST(Inet_Pton_Linkname, "")
#endif /* HAVE_SOCKETS */
diff --git a/gcc/ada/s-osinte-aix.ads b/gcc/ada/s-osinte-aix.ads
index b1639a77e3f..64907fb3052 100644
--- a/gcc/ada/s-osinte-aix.ads
+++ b/gcc/ada/s-osinte-aix.ads
@@ -7,7 +7,7 @@
-- S p e c --
-- --
-- Copyright (C) 1991-1994, Florida State University --
--- Copyright (C) 1995-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1995-2009, Free Software Foundation, Inc. --
-- --
-- GNARL is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -310,7 +310,7 @@ package System.OS_Interface is
function Get_Page_Size return size_t;
function Get_Page_Size return Address;
pragma Import (C, Get_Page_Size, "getpagesize");
- -- Returns the size of a page, or 0 if this is not relevant on this target
+ -- Returns the size of a page
PROT_NONE : constant := 0;
PROT_READ : constant := 1;
diff --git a/gcc/ada/s-osinte-darwin.ads b/gcc/ada/s-osinte-darwin.ads
index 99bdc6d8ea6..ed2f93124a0 100644
--- a/gcc/ada/s-osinte-darwin.ads
+++ b/gcc/ada/s-osinte-darwin.ads
@@ -294,7 +294,7 @@ package System.OS_Interface is
function Get_Page_Size return size_t;
function Get_Page_Size return System.Address;
pragma Import (C, Get_Page_Size, "getpagesize");
- -- Returns the size of a page, or 0 if this is not relevant on this target
+ -- Returns the size of a page
PROT_NONE : constant := 0;
PROT_READ : constant := 1;
diff --git a/gcc/ada/s-osinte-freebsd.ads b/gcc/ada/s-osinte-freebsd.ads
index c1ed40b7720..c8378292168 100644
--- a/gcc/ada/s-osinte-freebsd.ads
+++ b/gcc/ada/s-osinte-freebsd.ads
@@ -7,7 +7,7 @@
-- S p e c --
-- --
-- Copyright (C) 1991-1994, Florida State University --
--- Copyright (C) 1995-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1995-2009, Free Software Foundation, Inc. --
-- --
-- GNARL is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -326,7 +326,7 @@ package System.OS_Interface is
function Get_Page_Size return size_t;
function Get_Page_Size return Address;
pragma Import (C, Get_Page_Size, "getpagesize");
- -- returns the size of a page, or 0 if this is not relevant on this target
+ -- Returns the size of a page
PROT_NONE : constant := 0;
PROT_READ : constant := 1;
diff --git a/gcc/ada/s-osinte-hpux-dce.adb b/gcc/ada/s-osinte-hpux-dce.adb
index 45a5ed1dc56..8844d17e0b2 100644
--- a/gcc/ada/s-osinte-hpux-dce.adb
+++ b/gcc/ada/s-osinte-hpux-dce.adb
@@ -7,7 +7,7 @@
-- B o d y --
-- --
-- Copyright (C) 1991-1994, Florida State University --
--- Copyright (C) 1995-2007, AdaCore --
+-- Copyright (C) 1995-2009, AdaCore --
-- --
-- GNARL is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -314,11 +314,7 @@ package body System.OS_Interface is
begin
if pthread_cond_timedwait_base (cond, mutex, abstime) /= 0 then
- if errno = EAGAIN then
- return ETIMEDOUT;
- else
- return errno;
- end if;
+ return (if errno = EAGAIN then ETIMEDOUT else errno);
else
return 0;
end if;
diff --git a/gcc/ada/s-osinte-hpux.ads b/gcc/ada/s-osinte-hpux.ads
index 5c4003d30a3..ea31697a4ed 100644
--- a/gcc/ada/s-osinte-hpux.ads
+++ b/gcc/ada/s-osinte-hpux.ads
@@ -7,7 +7,7 @@
-- S p e c --
-- --
-- Copyright (C) 1991-1994, Florida State University --
--- Copyright (C) 1995-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1995-2009, Free Software Foundation, Inc. --
-- --
-- GNARL is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -300,7 +300,7 @@ package System.OS_Interface is
function Get_Page_Size return size_t;
function Get_Page_Size return Address;
pragma Import (C, Get_Page_Size, "getpagesize");
- -- Returns the size of a page, or 0 if this is not relevant on this target
+ -- Returns the size of a page
PROT_NONE : constant := 0;
PROT_READ : constant := 1;
diff --git a/gcc/ada/s-osinte-solaris-posix.ads b/gcc/ada/s-osinte-solaris-posix.ads
index c5885e72a9a..517ed52c100 100644
--- a/gcc/ada/s-osinte-solaris-posix.ads
+++ b/gcc/ada/s-osinte-solaris-posix.ads
@@ -7,7 +7,7 @@
-- S p e c --
-- --
-- Copyright (C) 1991-1994, Florida State University --
--- Copyright (C) 1995-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1995-2009, Free Software Foundation, Inc. --
-- --
-- GNARL is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -294,7 +294,7 @@ package System.OS_Interface is
function Get_Page_Size return size_t;
function Get_Page_Size return Address;
pragma Import (C, Get_Page_Size, "getpagesize");
- -- Returns the size of a page, or 0 if this is not relevant on this target
+ -- Returns the size of a page
PROT_NONE : constant := 0;
PROT_READ : constant := 1;
diff --git a/gcc/ada/s-osinte-tru64.adb b/gcc/ada/s-osinte-tru64.adb
index 8252107a313..ad391bcb473 100644
--- a/gcc/ada/s-osinte-tru64.adb
+++ b/gcc/ada/s-osinte-tru64.adb
@@ -99,11 +99,10 @@ package body System.OS_Interface is
-- Stick a guard page right above the Yellow Zone if it exists
if Teb.all.stack_yellow /= Teb.all.stack_guard then
- if Hide then
- Res := mprotect (Teb.all.stack_yellow, Get_Page_Size, PROT_ON);
- else
- Res := mprotect (Teb.all.stack_yellow, Get_Page_Size, PROT_OFF);
- end if;
+ Res :=
+ mprotect
+ (Teb.all.stack_yellow, Get_Page_Size,
+ prot => (if Hide then PROT_ON else PROT_OFF));
end if;
end Hide_Unhide_Yellow_Zone;
diff --git a/gcc/ada/s-osinte-tru64.ads b/gcc/ada/s-osinte-tru64.ads
index efb739f8f50..e893eedb399 100644
--- a/gcc/ada/s-osinte-tru64.ads
+++ b/gcc/ada/s-osinte-tru64.ads
@@ -7,7 +7,7 @@
-- S p e c --
-- --
-- Copyright (C) 1991-1994, Florida State University --
--- Copyright (C) 1995-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1995-2009, Free Software Foundation, Inc. --
-- --
-- GNARL is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -286,7 +286,7 @@ package System.OS_Interface is
function Get_Page_Size return size_t;
function Get_Page_Size return Address;
pragma Import (C, Get_Page_Size, "getpagesize");
- -- Returns the size of a page, or 0 if this is not relevant on this target
+ -- Returns the size of a page
PROT_NONE : constant := 0;
PROT_READ : constant := 1;
diff --git a/gcc/ada/s-osprim-mingw.adb b/gcc/ada/s-osprim-mingw.adb
index 4a916166535..c818811ed1a 100644
--- a/gcc/ada/s-osprim-mingw.adb
+++ b/gcc/ada/s-osprim-mingw.adb
@@ -156,15 +156,17 @@ package body System.OS_Primitives is
-- Therefore, the elapsed time reported by GetSystemTime between both
-- actions should be null.
- Max_Elapsed : constant := 0;
epoch_1970 : constant := 16#19D_B1DE_D53E_8000#; -- win32 UTC epoch
system_time_ns : constant := 100; -- 100 ns per tick
Sec_Unit : constant := 10#1#E9;
- Test_Now : aliased Long_Long_Integer;
- Loc_Ticks : aliased LARGE_INTEGER;
- Loc_Time : aliased Long_Long_Integer;
- Elapsed : Long_Long_Integer;
- Current_Max : Long_Long_Integer := Long_Long_Integer'Last;
+ Max_Elapsed : constant LARGE_INTEGER :=
+ LARGE_INTEGER (Tick_Frequency / 100_000);
+ -- Look for a precision of 0.01 ms
+
+ Loc_Ticks, Ctrl_Ticks : aliased LARGE_INTEGER;
+ Loc_Time, Ctrl_Time : aliased Long_Long_Integer;
+ Elapsed : LARGE_INTEGER;
+ Current_Max : LARGE_INTEGER := LARGE_INTEGER'Last;
begin
-- Here we must be sure that both of these calls are done in a short
@@ -182,8 +184,6 @@ package body System.OS_Primitives is
-- during the runs.
for K in 1 .. 10 loop
- GetSystemTimeAsFileTime (Loc_Time'Access);
-
if QueryPerformanceCounter (Loc_Ticks'Access) = Win32.FALSE then
pragma Assert
(Standard.False,
@@ -191,17 +191,36 @@ package body System.OS_Primitives is
null;
end if;
- GetSystemTimeAsFileTime (Test_Now'Access);
+ GetSystemTimeAsFileTime (Ctrl_Time'Access);
+
+ -- Scan for clock tick, will take upto 16ms/1ms depending on PC.
+ -- This cannot be an infinite loop or the system hardware is badly
+ -- dammaged.
+
+ loop
+ GetSystemTimeAsFileTime (Loc_Time'Access);
+ if QueryPerformanceCounter (Ctrl_Ticks'Access) = Win32.FALSE then
+ pragma Assert
+ (Standard.False,
+ "Could not query high performance counter in Clock");
+ null;
+ end if;
+ exit when Loc_Time /= Ctrl_Time;
+ Loc_Ticks := Ctrl_Ticks;
+ end loop;
- Elapsed := Test_Now - Loc_Time;
+ -- Check elapsed Performance Counter between samples
+ -- to choose the best one.
+
+ Elapsed := Ctrl_Ticks - Loc_Ticks;
if Elapsed < Current_Max then
Base_Time := Loc_Time;
Base_Ticks := Loc_Ticks;
Current_Max := Elapsed;
+ -- Exit the loop when we have reached the expected precision
+ exit when Elapsed <= Max_Elapsed;
end if;
-
- exit when Elapsed = Max_Elapsed;
end loop;
Base_Clock := Duration
diff --git a/gcc/ada/s-parame.adb b/gcc/ada/s-parame.adb
index 63eae6e2f95..ff61b7ee572 100644
--- a/gcc/ada/s-parame.adb
+++ b/gcc/ada/s-parame.adb
@@ -31,6 +31,8 @@
-- This is the default (used on all native platforms) version of this package
+pragma Compiler_Unit;
+
package body System.Parameters is
-------------------------
diff --git a/gcc/ada/s-parame.ads b/gcc/ada/s-parame.ads
index 511951386c6..2110034ec6b 100644
--- a/gcc/ada/s-parame.ads
+++ b/gcc/ada/s-parame.ads
@@ -46,6 +46,8 @@
-- Note: do not introduce any pragma Inline statements into this unit, since
-- otherwise the relinking and rebinding capability would be deactivated.
+pragma Compiler_Unit;
+
package System.Parameters is
pragma Pure;
diff --git a/gcc/ada/s-restri.adb b/gcc/ada/s-restri.adb
index 2db0e794a28..7ce6da9cc46 100644
--- a/gcc/ada/s-restri.adb
+++ b/gcc/ada/s-restri.adb
@@ -29,6 +29,8 @@
-- --
------------------------------------------------------------------------------
+pragma Compiler_Unit;
+
package body System.Restrictions is
use Rident;
diff --git a/gcc/ada/s-restri.ads b/gcc/ada/s-restri.ads
index e9a72aa9f9b..cd447c1b0b4 100644
--- a/gcc/ada/s-restri.ads
+++ b/gcc/ada/s-restri.ads
@@ -38,6 +38,8 @@
-- with names discarded, so that we do not have image tables for the
-- large restriction enumeration types at run time.
+pragma Compiler_Unit;
+
with System.Rident;
package System.Restrictions is
diff --git a/gcc/ada/s-stausa.adb b/gcc/ada/s-stausa.adb
index dfa8a1fc6bb..37dda6fad3c 100644
--- a/gcc/ada/s-stausa.adb
+++ b/gcc/ada/s-stausa.adb
@@ -609,20 +609,18 @@ package body System.Stack_Usage is
-- Take either the label size or the number image size for the
-- size of the column "Stack Size".
- if Size_Str_Len > Stack_Size_Str'Length then
- Max_Stack_Size_Len := Size_Str_Len;
- else
- Max_Stack_Size_Len := Stack_Size_Str'Length;
- end if;
+ Max_Stack_Size_Len :=
+ (if Size_Str_Len > Stack_Size_Str'Length
+ then Size_Str_Len
+ else Stack_Size_Str'Length);
-- Take either the label size or the number image size for the
- -- size of the column "Stack Usage"
+ -- size of the column "Stack Usage".
- if Result_Str_Len > Actual_Size_Str'Length then
- Max_Actual_Use_Len := Result_Str_Len;
- else
- Max_Actual_Use_Len := Actual_Size_Str'Length;
- end if;
+ Max_Actual_Use_Len :=
+ (if Result_Str_Len > Actual_Size_Str'Length
+ then Result_Str_Len
+ else Actual_Size_Str'Length);
Output_Result
(Analyzer.Result_Id,
diff --git a/gcc/ada/s-stchop-vxworks.adb b/gcc/ada/s-stchop-vxworks.adb
index 9552d570fc0..152dc920bcf 100644
--- a/gcc/ada/s-stchop-vxworks.adb
+++ b/gcc/ada/s-stchop-vxworks.adb
@@ -31,7 +31,7 @@
-- This is the VxWorks version of this package.
-- This file should be kept synchronized with the general implementation
--- provided by s-stchop.adb.
+-- provided by s-stchop.adb. This version is for VxWorks 5 and VxWorks MILS.
pragma Restrictions (No_Elaboration_Code);
-- We want to guarantee the absence of elaboration code because the
@@ -44,10 +44,11 @@ with Interfaces.C;
package body System.Stack_Checking.Operations is
-- In order to have stack checking working appropriately on VxWorks we need
- -- to extract the stack size information from the VxWorks kernel itself. It
- -- means that the library for showing task-related information needs to be
- -- linked into the VxWorks system, when using stack checking. The TaskShow
- -- library can be linked into the VxWorks system by either:
+ -- to extract the stack size information from the VxWorks kernel itself.
+
+ -- For VxWorks 5 the library for showing task-related information needs to
+ -- be linked into the VxWorks system, when using stack checking. The
+ -- taskShow library can be linked into the VxWorks system by either:
-- * defining INCLUDE_SHOW_ROUTINES in config.h when using
-- configuration header files, or
@@ -55,6 +56,9 @@ package body System.Stack_Checking.Operations is
-- * selecting INCLUDE_TASK_SHOW when using the Tornado project
-- facility.
+ -- VxWorks MILS includes the necessary routine in taskLib, so nothing
+ -- special needs to be done there.
+
Stack_Limit : Address :=
Boolean'Pos (Stack_Grows_Down) * Address'First
+ Boolean'Pos (not Stack_Grows_Down) * Address'Last;
@@ -129,6 +133,9 @@ package body System.Stack_Checking.Operations is
Get_Stack_Info (Stack_Info'Access);
+ -- In s-stchop.adb, we check for overflow in the following operations,
+ -- but we have no such check in this vxworks version. Why not ???
+
if Stack_Grows_Down then
Limit := Stack_Info.Base - Storage_Offset (Stack_Info.Size);
else
diff --git a/gcc/ada/s-stchop.adb b/gcc/ada/s-stchop.adb
index 7c62aa5e550..d4aa675a857 100644
--- a/gcc/ada/s-stchop.adb
+++ b/gcc/ada/s-stchop.adb
@@ -149,11 +149,9 @@ package body System.Stack_Checking.Operations is
-- If a stack base address has been registered, honor it. Fallback to
-- the address of a local object otherwise.
- if My_Stack.Limit /= System.Null_Address then
- My_Stack.Base := My_Stack.Limit;
- else
- My_Stack.Base := Frame_Address;
- end if;
+ My_Stack.Base :=
+ (if My_Stack.Limit /= System.Null_Address
+ then My_Stack.Limit else Frame_Address);
if Stack_Grows_Down then
diff --git a/gcc/ada/s-strhas.adb b/gcc/ada/s-strhas.adb
index b83823050e6..0e86cb66b31 100644
--- a/gcc/ada/s-strhas.adb
+++ b/gcc/ada/s-strhas.adb
@@ -29,6 +29,8 @@
-- --
------------------------------------------------------------------------------
+pragma Compiler_Unit;
+
package body System.String_Hash is
-- Compute a hash value for a key. The approach here is follows the
diff --git a/gcc/ada/s-strxdr.adb b/gcc/ada/s-strxdr.adb
index 32ee8ee433d..4fca719e25d 100644
--- a/gcc/ada/s-strxdr.adb
+++ b/gcc/ada/s-strxdr.adb
@@ -1263,11 +1263,9 @@ package body System.Stream_Attributes is
else
-- Test sign and apply two complement notation
- if Item < 0 then
- U := XDR_U'Last xor XDR_U (-(Item + 1));
- else
- U := XDR_U (Item);
- end if;
+ U := (if Item < 0
+ then XDR_U'Last xor XDR_U (-(Item + 1))
+ else XDR_U (Item));
for N in reverse S'Range loop
S (N) := SE (U mod BB);
@@ -1386,8 +1384,7 @@ package body System.Stream_Attributes is
X := Long_Unsigned (Item);
end if;
- -- Compute using machine unsigned
- -- rather than long_unsigned.
+ -- Compute using machine unsigned rather than long_unsigned
for N in reverse S'Range loop
@@ -1530,8 +1527,7 @@ package body System.Stream_Attributes is
X := Long_Long_Unsigned (Item);
end if;
- -- Compute using machine unsigned
- -- rather than long_long_unsigned.
+ -- Compute using machine unsigned rather than long_long_unsigned
for N in reverse S'Range loop
@@ -1571,8 +1567,7 @@ package body System.Stream_Attributes is
S := Long_Long_Unsigned_To_XDR_S_LLU (Item);
else
- -- Compute using machine unsigned
- -- rather than long_long_unsigned.
+ -- Compute using machine unsigned rather than long_long_unsigned
for N in reverse S'Range loop
@@ -1609,8 +1604,7 @@ package body System.Stream_Attributes is
S := Long_Long_Unsigned_To_XDR_S_LU (Long_Long_Unsigned (Item));
else
- -- Compute using machine unsigned
- -- rather than long_unsigned.
+ -- Compute using machine unsigned rather than long_unsigned
for N in reverse S'Range loop
@@ -1729,11 +1723,9 @@ package body System.Stream_Attributes is
else
-- Test sign and apply two complement's notation
- if Item < 0 then
- U := XDR_SU'Last xor XDR_SU (-(Item + 1));
- else
- U := XDR_SU (Item);
- end if;
+ U := (if Item < 0
+ then XDR_SU'Last xor XDR_SU (-(Item + 1))
+ else XDR_SU (Item));
for N in reverse S'Range loop
S (N) := SE (U mod BB);
@@ -1766,11 +1758,9 @@ package body System.Stream_Attributes is
else
-- Test sign and apply two complement's notation
- if Item < 0 then
- U := XDR_SSU'Last xor XDR_SSU (-(Item + 1));
- else
- U := XDR_SSU (Item);
- end if;
+ U := (if Item < 0
+ then XDR_SSU'Last xor XDR_SSU (-(Item + 1))
+ else XDR_SSU (Item));
S (1) := SE (U);
end if;
diff --git a/gcc/ada/s-taenca.adb b/gcc/ada/s-taenca.adb
index df8a5735333..fba7691e3a2 100644
--- a/gcc/ada/s-taenca.adb
+++ b/gcc/ada/s-taenca.adb
@@ -165,13 +165,8 @@ package body System.Tasking.Entry_Calls is
and then Entry_Call.State = Now_Abortable
then
Queuing.Dequeue_Call (Entry_Call);
-
- if Entry_Call.Cancellation_Attempted then
- Entry_Call.State := Cancelled;
- else
- Entry_Call.State := Done;
- end if;
-
+ Entry_Call.State :=
+ (if Entry_Call.Cancellation_Attempted then Cancelled else Done);
Unlock_And_Update_Server (Self_ID, Entry_Call);
else
diff --git a/gcc/ada/s-taprop-dummy.adb b/gcc/ada/s-taprop-dummy.adb
index 38264ba5c88..645e9fd90ba 100644
--- a/gcc/ada/s-taprop-dummy.adb
+++ b/gcc/ada/s-taprop-dummy.adb
@@ -38,8 +38,6 @@ pragma Polling (Off);
-- Turn off polling, we do not want ATC polling to take place during tasking
-- operations. It causes infinite loops and other problems.
-with System.Error_Reporting;
-
package body System.Task_Primitives.Operations is
use System.Tasking;
@@ -192,9 +190,7 @@ package body System.Task_Primitives.Operations is
procedure Initialize (Environment_Task : Task_Id) is
No_Tasking : Boolean;
begin
- No_Tasking :=
- System.Error_Reporting.Shutdown
- ("Tasking not implemented on this configuration");
+ raise Program_Error with "tasking not implemented on this configuration";
end Initialize;
procedure Initialize (S : in out Suspension_Object) is
diff --git a/gcc/ada/s-taprop-hpux-dce.adb b/gcc/ada/s-taprop-hpux-dce.adb
index e93b7af4dca..ebc2f9ddc0c 100644
--- a/gcc/ada/s-taprop-hpux-dce.adb
+++ b/gcc/ada/s-taprop-hpux-dce.adb
@@ -411,16 +411,14 @@ package body System.Task_Primitives.Operations is
pragma Unreferenced (Reason);
Result : Interfaces.C.int;
+
begin
- if Single_Lock then
- Result :=
- pthread_cond_wait
- (Self_ID.Common.LL.CV'Access, Single_RTS_Lock'Access);
- else
- Result :=
- pthread_cond_wait
- (Self_ID.Common.LL.CV'Access, Self_ID.Common.LL.L'Access);
- end if;
+ Result :=
+ pthread_cond_wait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access));
-- EINTR is not considered a failure
@@ -450,11 +448,10 @@ package body System.Task_Primitives.Operations is
Timedout := True;
Yielded := False;
- if Mode = Relative then
- Abs_Time := Duration'Min (Time, Max_Sensible_Delay) + Check_Time;
- else
- Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
- end if;
+ Abs_Time :=
+ (if Mode = Relative
+ then Duration'Min (Time, Max_Sensible_Delay) + Check_Time
+ else Duration'Min (Check_Time + Max_Sensible_Delay, Time));
if Abs_Time > Check_Time then
Request := To_Timespec (Abs_Time);
@@ -462,20 +459,13 @@ package body System.Task_Primitives.Operations is
loop
exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
- if Single_Lock then
- Result :=
- pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Single_RTS_Lock'Access,
- Request'Access);
-
- else
- Result :=
- pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Self_ID.Common.LL.L'Access,
- Request'Access);
- end if;
+ Result :=
+ pthread_cond_timedwait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access),
+ abstime => Request'Access);
exit when Abs_Time <= Monotonic_Clock;
@@ -515,11 +505,10 @@ package body System.Task_Primitives.Operations is
Write_Lock (Self_ID);
- if Mode = Relative then
- Abs_Time := Time + Check_Time;
- else
- Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
- end if;
+ Abs_Time :=
+ (if Mode = Relative
+ then Time + Check_Time
+ else Duration'Min (Check_Time + Max_Sensible_Delay, Time));
if Abs_Time > Check_Time then
Request := To_Timespec (Abs_Time);
@@ -528,19 +517,13 @@ package body System.Task_Primitives.Operations is
loop
exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
- if Single_Lock then
- Result :=
- pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Single_RTS_Lock'Access,
- Request'Access);
- else
- Result :=
- pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Self_ID.Common.LL.L'Access,
- Request'Access);
- end if;
+ Result :=
+ pthread_cond_timedwait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access),
+ abstime => Request'Access);
exit when Abs_Time <= Monotonic_Clock;
diff --git a/gcc/ada/s-taprop-irix.adb b/gcc/ada/s-taprop-irix.adb
index 83439214259..e73555fb304 100644
--- a/gcc/ada/s-taprop-irix.adb
+++ b/gcc/ada/s-taprop-irix.adb
@@ -430,15 +430,12 @@ package body System.Task_Primitives.Operations is
Result : Interfaces.C.int;
begin
- if Single_Lock then
- Result :=
- pthread_cond_wait
- (Self_ID.Common.LL.CV'Access, Single_RTS_Lock'Access);
- else
- Result :=
- pthread_cond_wait
- (Self_ID.Common.LL.CV'Access, Self_ID.Common.LL.L'Access);
- end if;
+ Result :=
+ pthread_cond_wait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access));
-- EINTR is not considered a failure
@@ -469,11 +466,10 @@ package body System.Task_Primitives.Operations is
Timedout := True;
Yielded := False;
- if Mode = Relative then
- Abs_Time := Duration'Min (Time, Max_Sensible_Delay) + Check_Time;
- else
- Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
- end if;
+ Abs_Time :=
+ (if Mode = Relative
+ then Duration'Min (Time, Max_Sensible_Delay) + Check_Time
+ else Duration'Min (Check_Time + Max_Sensible_Delay, Time));
if Abs_Time > Check_Time then
Request := To_Timespec (Abs_Time);
@@ -481,18 +477,13 @@ package body System.Task_Primitives.Operations is
loop
exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
- if Single_Lock then
- Result :=
- pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access, Single_RTS_Lock'Access,
- Request'Access);
-
- else
- Result :=
- pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access, Self_ID.Common.LL.L'Access,
- Request'Access);
- end if;
+ Result :=
+ pthread_cond_timedwait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access),
+ abstime => Request'Access);
Check_Time := Monotonic_Clock;
exit when Abs_Time <= Check_Time or else Check_Time < Base_Time;
@@ -530,11 +521,10 @@ package body System.Task_Primitives.Operations is
Write_Lock (Self_ID);
- if Mode = Relative then
- Abs_Time := Time + Check_Time;
- else
- Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
- end if;
+ Abs_Time :=
+ (if Mode = Relative
+ then Time + Check_Time
+ else Duration'Min (Check_Time + Max_Sensible_Delay, Time));
if Abs_Time > Check_Time then
Request := To_Timespec (Abs_Time);
@@ -543,17 +533,13 @@ package body System.Task_Primitives.Operations is
loop
exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
- if Single_Lock then
- Result := pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Single_RTS_Lock'Access,
- Request'Access);
- else
- Result := pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Self_ID.Common.LL.L'Access,
- Request'Access);
- end if;
+ Result :=
+ pthread_cond_timedwait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access),
+ abstime => Request'Access);
Check_Time := Monotonic_Clock;
exit when Abs_Time <= Check_Time or else Check_Time < Base_Time;
diff --git a/gcc/ada/s-taprop-linux.adb b/gcc/ada/s-taprop-linux.adb
index 0f0773cec5e..5680fa22c76 100644
--- a/gcc/ada/s-taprop-linux.adb
+++ b/gcc/ada/s-taprop-linux.adb
@@ -426,15 +426,12 @@ package body System.Task_Primitives.Operations is
begin
pragma Assert (Self_ID = Self);
- if Single_Lock then
- Result :=
- pthread_cond_wait
- (Self_ID.Common.LL.CV'Access, Single_RTS_Lock'Access);
- else
- Result :=
- pthread_cond_wait
- (Self_ID.Common.LL.CV'Access, Self_ID.Common.LL.L'Access);
- end if;
+ Result :=
+ pthread_cond_wait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access));
-- EINTR is not considered a failure
@@ -469,11 +466,10 @@ package body System.Task_Primitives.Operations is
Timedout := True;
Yielded := False;
- if Mode = Relative then
- Abs_Time := Duration'Min (Time, Max_Sensible_Delay) + Check_Time;
- else
- Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
- end if;
+ Abs_Time :=
+ (if Mode = Relative
+ then Duration'Min (Time, Max_Sensible_Delay) + Check_Time
+ else Duration'Min (Check_Time + Max_Sensible_Delay, Time));
if Abs_Time > Check_Time then
Request := To_Timespec (Abs_Time);
@@ -481,20 +477,13 @@ package body System.Task_Primitives.Operations is
loop
exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
- if Single_Lock then
- Result :=
- pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Single_RTS_Lock'Access,
- Request'Access);
-
- else
- Result :=
- pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Self_ID.Common.LL.L'Access,
- Request'Access);
- end if;
+ Result :=
+ pthread_cond_timedwait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access),
+ abstime => Request'Access);
Check_Time := Monotonic_Clock;
exit when Abs_Time <= Check_Time or else Check_Time < Base_Time;
@@ -539,11 +528,10 @@ package body System.Task_Primitives.Operations is
Write_Lock (Self_ID);
- if Mode = Relative then
- Abs_Time := Time + Check_Time;
- else
- Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
- end if;
+ Abs_Time :=
+ (if Mode = Relative
+ then Time + Check_Time
+ else Duration'Min (Check_Time + Max_Sensible_Delay, Time));
if Abs_Time > Check_Time then
Request := To_Timespec (Abs_Time);
@@ -552,17 +540,13 @@ package body System.Task_Primitives.Operations is
loop
exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
- if Single_Lock then
- Result := pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Single_RTS_Lock'Access,
- Request'Access);
- else
- Result := pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Self_ID.Common.LL.L'Access,
- Request'Access);
- end if;
+ Result :=
+ pthread_cond_timedwait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access),
+ abstime => Request'Access);
Check_Time := Monotonic_Clock;
exit when Abs_Time <= Check_Time or else Check_Time < Base_Time;
@@ -1104,6 +1088,7 @@ package body System.Task_Primitives.Operations is
SSL.Abort_Undefer.all;
raise Program_Error;
+
else
-- Suspend the task if the state is False. Otherwise, the task
-- continues its execution, and the state of the suspension object
@@ -1118,8 +1103,7 @@ package body System.Task_Primitives.Operations is
-- Loop in case pthread_cond_wait returns earlier than expected
-- (e.g. in case of EINTR caused by a signal). This should not
-- happen with the current Linux implementation of pthread, but
- -- POSIX does not guarantee it, so this may change in the
- -- future.
+ -- POSIX does not guarantee it so this may change in future.
Result := pthread_cond_wait (S.CV'Access, S.L'Access);
pragma Assert (Result = 0 or else Result = EINTR);
diff --git a/gcc/ada/s-taprop-mingw.adb b/gcc/ada/s-taprop-mingw.adb
index cb51841a54d..a3b19ab5c5d 100644
--- a/gcc/ada/s-taprop-mingw.adb
+++ b/gcc/ada/s-taprop-mingw.adb
@@ -312,18 +312,17 @@ package body System.Task_Primitives.Operations is
Unlock (L, Global_Lock => True);
-- No problem if we are interrupted here: if the condition is signaled,
- -- WaitForSingleObject will simply not block
+ -- WaitForSingleObject will simply not block.
if Rel_Time <= 0.0 then
Timed_Out := True;
Wait_Result := 0;
else
- if Rel_Time >= Duration (Time_Out_Max) / 1000 then
- Time_Out := Time_Out_Max;
- else
- Time_Out := DWORD (Rel_Time * 1000);
- end if;
+ Time_Out :=
+ (if Rel_Time >= Duration (Time_Out_Max) / 1000
+ then Time_Out_Max
+ else DWORD (Rel_Time * 1000));
Wait_Result := WaitForSingleObject (HANDLE (Cond.all), Time_Out);
diff --git a/gcc/ada/s-taprop-posix.adb b/gcc/ada/s-taprop-posix.adb
index db385c8c589..d05bb1cd2d4 100644
--- a/gcc/ada/s-taprop-posix.adb
+++ b/gcc/ada/s-taprop-posix.adb
@@ -244,12 +244,9 @@ package body System.Task_Primitives.Operations is
Guard_Page_Address :=
Stack_Base - (Stack_Base mod Get_Page_Size) + Get_Page_Size;
- if On then
- Res := mprotect (Guard_Page_Address, Get_Page_Size, PROT_ON);
- else
- Res := mprotect (Guard_Page_Address, Get_Page_Size, PROT_OFF);
- end if;
-
+ Res :=
+ mprotect (Guard_Page_Address, Get_Page_Size,
+ prot => (if On then PROT_ON else PROT_OFF));
pragma Assert (Res = 0);
end if;
end Stack_Guard;
@@ -491,15 +488,12 @@ package body System.Task_Primitives.Operations is
Result : Interfaces.C.int;
begin
- if Single_Lock then
- Result :=
- pthread_cond_wait
- (Self_ID.Common.LL.CV'Access, Single_RTS_Lock'Access);
- else
- Result :=
- pthread_cond_wait
- (Self_ID.Common.LL.CV'Access, Self_ID.Common.LL.L'Access);
- end if;
+ Result :=
+ pthread_cond_wait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access));
-- EINTR is not considered a failure
@@ -551,27 +545,19 @@ package body System.Task_Primitives.Operations is
end if;
if Abs_Time > Check_Time then
- if Relative_Timed_Wait then
- Request := To_Timespec (Rel_Time);
- else
- Request := To_Timespec (Abs_Time);
- end if;
+ Request :=
+ To_Timespec (if Relative_Timed_Wait then Rel_Time else Abs_Time);
loop
exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
- if Single_Lock then
- Result :=
- pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access, Single_RTS_Lock'Access,
- Request'Access);
-
- else
- Result :=
- pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access, Self_ID.Common.LL.L'Access,
- Request'Access);
- end if;
+ Result :=
+ pthread_cond_timedwait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access),
+ abstime => Request'Access);
Check_Time := Monotonic_Clock;
exit when Abs_Time <= Check_Time or else Check_Time < Base_Time;
@@ -633,28 +619,20 @@ package body System.Task_Primitives.Operations is
end if;
if Abs_Time > Check_Time then
- if Relative_Timed_Wait then
- Request := To_Timespec (Rel_Time);
- else
- Request := To_Timespec (Abs_Time);
- end if;
-
+ Request :=
+ To_Timespec (if Relative_Timed_Wait then Rel_Time else Abs_Time);
Self_ID.Common.State := Delay_Sleep;
loop
exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
- if Single_Lock then
- Result := pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Single_RTS_Lock'Access,
- Request'Access);
- else
- Result := pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Self_ID.Common.LL.L'Access,
- Request'Access);
- end if;
+ Result :=
+ pthread_cond_timedwait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access),
+ abstime => Request'Access);
Check_Time := Monotonic_Clock;
exit when Abs_Time <= Check_Time or else Check_Time < Base_Time;
diff --git a/gcc/ada/s-taprop-solaris.adb b/gcc/ada/s-taprop-solaris.adb
index 1e47b9486ed..5250e0e2c15 100644
--- a/gcc/ada/s-taprop-solaris.adb
+++ b/gcc/ada/s-taprop-solaris.adb
@@ -1226,15 +1226,13 @@ package body System.Task_Primitives.Operations is
Timedout := True;
Yielded := False;
- if Mode = Relative then
- Abs_Time := Duration'Min (Time, Max_Sensible_Delay) + Check_Time;
- else
- Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
- end if;
+ Abs_Time :=
+ (if Mode = Relative
+ then Duration'Min (Time, Max_Sensible_Delay) + Check_Time
+ else Duration'Min (Check_Time + Max_Sensible_Delay, Time));
if Abs_Time > Check_Time then
Request := To_Timespec (Abs_Time);
-
loop
exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
@@ -1294,11 +1292,10 @@ package body System.Task_Primitives.Operations is
Write_Lock (Self_ID);
- if Mode = Relative then
- Abs_Time := Time + Check_Time;
- else
- Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
- end if;
+ Abs_Time :=
+ (if Mode = Relative
+ then Time + Check_Time
+ else Duration'Min (Check_Time + Max_Sensible_Delay, Time));
if Abs_Time > Check_Time then
Request := To_Timespec (Abs_Time);
diff --git a/gcc/ada/s-taprop-tru64.adb b/gcc/ada/s-taprop-tru64.adb
index c5a68b7a4e2..cd23f16d9ca 100644
--- a/gcc/ada/s-taprop-tru64.adb
+++ b/gcc/ada/s-taprop-tru64.adb
@@ -440,15 +440,12 @@ package body System.Task_Primitives.Operations is
Result : Interfaces.C.int;
begin
- if Single_Lock then
- Result :=
- pthread_cond_wait
- (Self_ID.Common.LL.CV'Access, Single_RTS_Lock'Access);
- else
- Result :=
- pthread_cond_wait
- (Self_ID.Common.LL.CV'Access, Self_ID.Common.LL.L'Access);
- end if;
+ Result :=
+ pthread_cond_wait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access));
-- EINTR is not considered a failure
@@ -482,11 +479,10 @@ package body System.Task_Primitives.Operations is
Timedout := True;
Yielded := False;
- if Mode = Relative then
- Abs_Time := Duration'Min (Time, Max_Sensible_Delay) + Check_Time;
- else
- Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
- end if;
+ Abs_Time :=
+ (if Mode = Relative
+ then Duration'Min (Time, Max_Sensible_Delay) + Check_Time
+ else Duration'Min (Check_Time + Max_Sensible_Delay, Time));
if Abs_Time > Check_Time then
Request := To_Timespec (Abs_Time);
@@ -494,20 +490,13 @@ package body System.Task_Primitives.Operations is
loop
exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
- if Single_Lock then
- Result :=
- pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Single_RTS_Lock'Access,
- Request'Access);
-
- else
- Result :=
- pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Self_ID.Common.LL.L'Access,
- Request'Access);
- end if;
+ Result :=
+ pthread_cond_timedwait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access),
+ abstime => Request'Access);
Check_Time := Monotonic_Clock;
exit when Abs_Time <= Check_Time or else Check_Time < Base_Time;
@@ -550,11 +539,10 @@ package body System.Task_Primitives.Operations is
Write_Lock (Self_ID);
- if Mode = Relative then
- Abs_Time := Time + Check_Time;
- else
- Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
- end if;
+ Abs_Time :=
+ (if Mode = Relative
+ then Time + Check_Time
+ else Duration'Min (Check_Time + Max_Sensible_Delay, Time));
if Abs_Time > Check_Time then
Request := To_Timespec (Abs_Time);
@@ -563,19 +551,13 @@ package body System.Task_Primitives.Operations is
loop
exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
- if Single_Lock then
- Result :=
- pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Single_RTS_Lock'Access,
- Request'Access);
- else
- Result :=
- pthread_cond_timedwait
- (Self_ID.Common.LL.CV'Access,
- Self_ID.Common.LL.L'Access,
- Request'Access);
- end if;
+ Result :=
+ pthread_cond_timedwait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access),
+ abstime => Request'Access);
Check_Time := Monotonic_Clock;
exit when Abs_Time <= Check_Time or else Check_Time < Base_Time;
diff --git a/gcc/ada/s-taprop-vms.adb b/gcc/ada/s-taprop-vms.adb
index eb8c0f1867c..582f88bcbde 100644
--- a/gcc/ada/s-taprop-vms.adb
+++ b/gcc/ada/s-taprop-vms.adb
@@ -408,15 +408,12 @@ package body System.Task_Primitives.Operations is
Result : Interfaces.C.int;
begin
- if Single_Lock then
- Result :=
- pthread_cond_wait
- (Self_ID.Common.LL.CV'Access, Single_RTS_Lock'Access);
- else
- Result :=
- pthread_cond_wait
- (Self_ID.Common.LL.CV'Access, Self_ID.Common.LL.L'Access);
- end if;
+ Result :=
+ pthread_cond_wait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access));
-- EINTR is not considered a failure
@@ -540,19 +537,13 @@ package body System.Task_Primitives.Operations is
exit;
end if;
- if Single_Lock then
- Result :=
- pthread_cond_wait
- (Self_ID.Common.LL.CV'Access,
- Single_RTS_Lock'Access);
- pragma Assert (Result = 0);
- else
- Result :=
- pthread_cond_wait
- (Self_ID.Common.LL.CV'Access,
- Self_ID.Common.LL.L'Access);
- pragma Assert (Result = 0);
- end if;
+ Result :=
+ pthread_cond_wait
+ (cond => Self_ID.Common.LL.CV'Access,
+ mutex => (if Single_Lock
+ then Single_RTS_Lock'Access
+ else Self_ID.Common.LL.L'Access));
+ pragma Assert (Result = 0);
Yielded := True;
diff --git a/gcc/ada/s-taprop-vxworks.adb b/gcc/ada/s-taprop-vxworks.adb
index 622e3b53230..4cde338bfd3 100644
--- a/gcc/ada/s-taprop-vxworks.adb
+++ b/gcc/ada/s-taprop-vxworks.adb
@@ -430,12 +430,10 @@ package body System.Task_Primitives.Operations is
-- Release the mutex before sleeping
- if Single_Lock then
- Result := semGive (Single_RTS_Lock.Mutex);
- else
- Result := semGive (Self_ID.Common.LL.L.Mutex);
- end if;
-
+ Result :=
+ semGive (if Single_Lock
+ then Single_RTS_Lock.Mutex
+ else Self_ID.Common.LL.L.Mutex);
pragma Assert (Result = 0);
-- Perform a blocking operation to take the CV semaphore. Note that a
@@ -448,12 +446,10 @@ package body System.Task_Primitives.Operations is
-- Take the mutex back
- if Single_Lock then
- Result := semTake (Single_RTS_Lock.Mutex, WAIT_FOREVER);
- else
- Result := semTake (Self_ID.Common.LL.L.Mutex, WAIT_FOREVER);
- end if;
-
+ Result :=
+ semTake ((if Single_Lock
+ then Single_RTS_Lock.Mutex
+ else Self_ID.Common.LL.L.Mutex), WAIT_FOREVER);
pragma Assert (Result = 0);
end Sleep;
@@ -506,12 +502,10 @@ package body System.Task_Primitives.Operations is
loop
-- Release the mutex before sleeping
- if Single_Lock then
- Result := semGive (Single_RTS_Lock.Mutex);
- else
- Result := semGive (Self_ID.Common.LL.L.Mutex);
- end if;
-
+ Result :=
+ semGive (if Single_Lock
+ then Single_RTS_Lock.Mutex
+ else Self_ID.Common.LL.L.Mutex);
pragma Assert (Result = 0);
-- Perform a blocking operation to take the CV semaphore. Note
@@ -551,12 +545,10 @@ package body System.Task_Primitives.Operations is
-- Take the mutex back
- if Single_Lock then
- Result := semTake (Single_RTS_Lock.Mutex, WAIT_FOREVER);
- else
- Result := semTake (Self_ID.Common.LL.L.Mutex, WAIT_FOREVER);
- end if;
-
+ Result :=
+ semTake ((if Single_Lock
+ then Single_RTS_Lock.Mutex
+ else Self_ID.Common.LL.L.Mutex), WAIT_FOREVER);
pragma Assert (Result = 0);
exit when Timedout or Wakeup;
@@ -623,11 +615,10 @@ package body System.Task_Primitives.Operations is
-- Modifying State, locking the TCB
- if Single_Lock then
- Result := semTake (Single_RTS_Lock.Mutex, WAIT_FOREVER);
- else
- Result := semTake (Self_ID.Common.LL.L.Mutex, WAIT_FOREVER);
- end if;
+ Result :=
+ semTake ((if Single_Lock
+ then Single_RTS_Lock.Mutex
+ else Self_ID.Common.LL.L.Mutex), WAIT_FOREVER);
pragma Assert (Result = 0);
@@ -639,11 +630,10 @@ package body System.Task_Primitives.Operations is
-- Release the TCB before sleeping
- if Single_Lock then
- Result := semGive (Single_RTS_Lock.Mutex);
- else
- Result := semGive (Self_ID.Common.LL.L.Mutex);
- end if;
+ Result :=
+ semGive (if Single_Lock
+ then Single_RTS_Lock.Mutex
+ else Self_ID.Common.LL.L.Mutex);
pragma Assert (Result = 0);
exit when Aborted;
@@ -670,11 +660,11 @@ package body System.Task_Primitives.Operations is
-- Take back the lock after having slept, to protect further
-- access to Self_ID.
- if Single_Lock then
- Result := semTake (Single_RTS_Lock.Mutex, WAIT_FOREVER);
- else
- Result := semTake (Self_ID.Common.LL.L.Mutex, WAIT_FOREVER);
- end if;
+ Result :=
+ semTake
+ ((if Single_Lock
+ then Single_RTS_Lock.Mutex
+ else Self_ID.Common.LL.L.Mutex), WAIT_FOREVER);
pragma Assert (Result = 0);
@@ -683,11 +673,11 @@ package body System.Task_Primitives.Operations is
Self_ID.Common.State := Runnable;
- if Single_Lock then
- Result := semGive (Single_RTS_Lock.Mutex);
- else
- Result := semGive (Self_ID.Common.LL.L.Mutex);
- end if;
+ Result :=
+ semGive
+ (if Single_Lock
+ then Single_RTS_Lock.Mutex
+ else Self_ID.Common.LL.L.Mutex);
else
taskDelay (0);
diff --git a/gcc/ada/s-tarest.adb b/gcc/ada/s-tarest.adb
index a29aed78a41..07ddbce8c60 100644
--- a/gcc/ada/s-tarest.adb
+++ b/gcc/ada/s-tarest.adb
@@ -340,11 +340,10 @@ package body System.Tasking.Restricted.Stages is
Write_Lock (C);
- if C.Common.Base_Priority < Get_Priority (Self_ID) then
- Activate_Prio := Get_Priority (Self_ID);
- else
- Activate_Prio := C.Common.Base_Priority;
- end if;
+ Activate_Prio :=
+ (if C.Common.Base_Priority < Get_Priority (Self_ID)
+ then Get_Priority (Self_ID)
+ else C.Common.Base_Priority);
STPO.Create_Task
(C, Task_Wrapper'Address,
@@ -477,11 +476,10 @@ package body System.Tasking.Restricted.Stages is
pragma Assert (Stack_Address = Null_Address);
- if Priority = Unspecified_Priority then
- Base_Priority := Self_ID.Common.Base_Priority;
- else
- Base_Priority := System.Any_Priority (Priority);
- end if;
+ Base_Priority :=
+ (if Priority = Unspecified_Priority
+ then Self_ID.Common.Base_Priority
+ else System.Any_Priority (Priority));
if Single_Lock then
Lock_RTS;
diff --git a/gcc/ada/s-tassta.adb b/gcc/ada/s-tassta.adb
index f56614ca7bd..a78b0d8f813 100644
--- a/gcc/ada/s-tassta.adb
+++ b/gcc/ada/s-tassta.adb
@@ -743,9 +743,7 @@ package body System.Tasking.Stages is
function State
(Int : System.Interrupt_Management.Interrupt_ID) return Character;
pragma Import (C, State, "__gnat_get_interrupt_state");
- -- Get interrupt state. Defined in a-init.c
- -- The input argument is the interrupt number,
- -- and the result is one of the following:
+ -- Get interrupt state for interrupt number Int. Defined in init.c
Default : constant Character := 's';
-- 's' Interrupt_State pragma set state to System (use "default"
diff --git a/gcc/ada/s-vxwext.adb b/gcc/ada/s-vxwext.adb
index b13b07e1641..a0f0e8a5910 100644
--- a/gcc/ada/s-vxwext.adb
+++ b/gcc/ada/s-vxwext.adb
@@ -31,7 +31,7 @@
-- This package provides vxworks specific support functions needed
-- by System.OS_Interface.
--- This is the VxWorks 5.x version of this package
+-- This is the VxWorks 5 and VxWorks MILS version of this package
package body System.VxWorks.Ext is
diff --git a/gcc/ada/s-vxwext.ads b/gcc/ada/s-vxwext.ads
index f1906a68734..42abdc1f355 100644
--- a/gcc/ada/s-vxwext.ads
+++ b/gcc/ada/s-vxwext.ads
@@ -29,7 +29,7 @@
-- This package provides vxworks specific support functions needed
-- by System.OS_Interface.
--- This is the VxWorks 5 version of this package
+-- This is the VxWorks 5 and VxWorks MILS version of this package
with Interfaces.C;
diff --git a/gcc/ada/scans.ads b/gcc/ada/scans.ads
index 4fe0700a4e4..770d53bb59b 100644
--- a/gcc/ada/scans.ads
+++ b/gcc/ada/scans.ads
@@ -428,7 +428,13 @@ package Scans is
-- Valid only when Token = Tok_String_Literal or Tok_Operator_Symbol.
Wide_Character_Found : Boolean := False;
- -- Set True if wide character found.
+ -- Set True if wide character found (i.e. a character that does not fit
+ -- in Character, but fits in Wide_Wide_Character).
+ -- Valid only when Token = Tok_String_Literal.
+
+ Wide_Wide_Character_Found : Boolean := False;
+ -- Set True if wide wide character found (i.e. a character that does
+ -- not fit in Character or Wide_Character).
-- Valid only when Token = Tok_String_Literal.
Special_Character : Character;
diff --git a/gcc/ada/scn.adb b/gcc/ada/scn.adb
index 81dc49bb5b5..98485506cba 100644
--- a/gcc/ada/scn.adb
+++ b/gcc/ada/scn.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -383,7 +383,10 @@ package body Scn is
when Tok_String_Literal =>
Token_Node := New_Node (N_String_Literal, Token_Ptr);
- Set_Has_Wide_Character (Token_Node, Wide_Character_Found);
+ Set_Has_Wide_Character
+ (Token_Node, Wide_Character_Found);
+ Set_Has_Wide_Wide_Character
+ (Token_Node, Wide_Wide_Character_Found);
Set_Strval (Token_Node, String_Literal_Id);
when Tok_Operator_Symbol =>
diff --git a/gcc/ada/scng.adb b/gcc/ada/scng.adb
index 30da224d905..af1f3bbc3a0 100644
--- a/gcc/ada/scng.adb
+++ b/gcc/ada/scng.adb
@@ -785,12 +785,12 @@ package body Scng is
procedure Set_String;
-- Procedure used to distinguish between string and operator symbol.
- -- On entry the string has been scanned out, and its characters
- -- start at Token_Ptr and end one character before Scan_Ptr. On exit
- -- Token is set to Tok_String_Literal or Tok_Operator_Symbol as
- -- appropriate, and Token_Node is appropriately initialized. In
- -- addition, in the operator symbol case, Token_Name is
- -- appropriately set.
+ -- On entry the string has been scanned out, and its characters start
+ -- at Token_Ptr and end one character before Scan_Ptr. On exit Token
+ -- is set to Tok_String_Literal/Tok_Operator_Symbol as appropriate,
+ -- and Token_Node is appropriately initialized. In addition, in the
+ -- operator symbol case, Token_Name is appropriately set, and the
+ -- flags [Wide_]Wide_Character_Found are set appropriately.
---------------------------
-- Error_Bad_String_Char --
@@ -1016,7 +1016,10 @@ package body Scng is
Delimiter := Source (Scan_Ptr);
Accumulate_Checksum (Delimiter);
+
Start_String;
+ Wide_Character_Found := False;
+ Wide_Wide_Character_Found := False;
Scan_Ptr := Scan_Ptr + 1;
-- Loop to scan out characters of string literal
@@ -1096,7 +1099,11 @@ package body Scng is
Store_String_Char (Code);
if not In_Character_Range (Code) then
- Wide_Character_Found := True;
+ if In_Wide_Character_Range (Code) then
+ Wide_Character_Found := True;
+ else
+ Wide_Wide_Character_Found := True;
+ end if;
end if;
end loop;
diff --git a/gcc/ada/scos.ads b/gcc/ada/scos.ads
index c58545f5ec1..cf2fb90392c 100644
--- a/gcc/ada/scos.ads
+++ b/gcc/ada/scos.ads
@@ -48,13 +48,17 @@ package SCOs is
-- Put_SCO reads the internal tables and generates text lines in the ALI
-- format.
+ -- ??? The specification below for the SCO ALI format and the internal
+ -- data structures have been modified, but the implementation has not been
+ -- updated yet to reflect these specification changes.
+
--------------------
-- SCO ALI Format --
--------------------
-- Source coverage obligations are generated on a unit-by-unit basis in the
-- ALI file, using lines that start with the identifying character C. These
- -- lines are generated if the -gnatC switch is set.
+ -- lines are generated if the -gnateS switch is set.
-- Sloc Ranges
@@ -75,7 +79,7 @@ package SCOs is
-- is divided into sections, one section for each unit for which SCO's
-- are generated. A SCO section has a header of the form:
- -- C dependency-number filename
+ -- C dependency-number filename
-- This header precedes SCO information for the unit identified by
-- dependency number and file name. The dependency number is the
@@ -102,31 +106,52 @@ package SCOs is
-- renaming_declaration
-- generic_instantiation
+ -- and the following regions of the syntax tree:
+
+ -- the part of a case_statement from CASE up to the expression
+ -- the part of a FOR iteration scheme from FOR up to the
+ -- loop_parameter_specification
+ -- the part of an extended_return_statement from RETURN up to the
+ -- expression (if present) or to the return_subtype_indication (if
+ -- no expression)
+
-- Statement lines
- -- These lines correspond to a sequence of one or more statements which
- -- are always executed in sequence, The first statement may be an entry
- -- point (e.g. statement after a label), and the last statement may be
- -- an exit point (e.g. an exit statement), but no other entry or exit
- -- points may occur within the sequence of statements. The idea is that
- -- the sequence can be treated as a single unit from a coverage point of
- -- view, if any of the code for the statement sequence is executed, this
- -- corresponds to coverage of the entire statement sequence. The form of
- -- a statement line in the ALI file is:
+ -- These lines correspond to one or more successive statements (in the
+ -- sense of the above list) which are always executed in sequence (in the
+ -- absence of exceptions or other external interruptions).
- -- CS sloc-range
+ -- Entry points to such sequences are:
- -- Exit points
+ -- the first statement of any sequence_of_statements
+ -- the first statement after a compound statement
+ -- the first statement after an EXIT, RAISE or GOTO statement
+ -- any statement with a label
- -- An exit point is a statement that causes transfer of control. Examples
- -- are exit statements, raise statements and return statements. The form
- -- of an exit point in the ALI file is:
+ -- Each entry point must appear as the first entry on a CS line.
+ -- The idea is that if any simple statement on a CS line is known to have
+ -- been executed, then all statements that appear before it on the same
+ -- CS line are certain to also have been executed.
- -- CT sloc-range
+ -- The form of a statement line in the ALI file is:
- -- Decisions
+ -- CS *sloc-range [*sloc-range...]
+
+ -- where each sloc-range corresponds to a single statement, and * is
+ -- one of:
+
+ -- t type declaration
+ -- s subtype declaration
+ -- o object declaration
+ -- r renaming declaration
+ -- i generic instantiation
+ -- C CASE statement
+ -- F FOR loop statement
+ -- R extended RETURN statement
- -- Decisions represent the most significant section of the SCO lines
+ -- and is omitted for all other cases.
+
+ -- Decisions
-- Note: in the following description, logical operator includes the
-- short circuited forms (so can be any of AND, OR, XOR, NOT, AND THEN,
@@ -136,7 +161,7 @@ package SCOs is
-- expresssion that occurs in the context of a control structure in the
-- source program, including WHILE, IF, EXIT WHEN. Note that a boolean
-- expression in any other context, for example, on the right side of an
- -- assignment, is not considered to be a decision.
+ -- assignment, is not considered to be a simple decision.
-- A complex decision is an occurrence of a logical operator which is not
-- itself an operand of some other logical operator. If any operand of
@@ -160,7 +185,7 @@ package SCOs is
-- For each decision, a decision line is generated with the form:
- -- C* expression
+ -- C*sloc expression
-- Here * is one of the following characters:
@@ -169,15 +194,23 @@ package SCOs is
-- W decision in WHILE iteration scheme
-- X decision appearing in some other expression context
+ -- For I, E, W, sloc is the source location of the IF, EXIT or WHILE
+ -- token.
+
+ -- For X, sloc is omitted.
+
-- The expression is a prefix polish form indicating the structure of
-- the decision, including logical operators and short circuit forms.
-- The following is a grammar showing the structure of expression:
-- expression ::= term (if expr is not logical operator)
- -- expression ::= & term term (if expr is AND or AND THEN)
- -- expression ::= | term term (if expr is OR or OR ELSE)
- -- expression ::= ^ term term (if expr is XOR)
- -- expression ::= !term (if expr is NOT)
+ -- expression ::= &sloc term term (if expr is AND or AND THEN)
+ -- expression ::= |sloc term term (if expr is OR or OR ELSE)
+ -- expression ::= ^sloc term term (if expr is XOR)
+ -- expression ::= !sloc term (if expr is NOT)
+
+ -- In the last four cases, sloc is the source location of the AND, OR,
+ -- XOR or NOT token, respectively.
-- term ::= element
-- term ::= expression
@@ -194,15 +227,15 @@ package SCOs is
-- the compiler as always being true or false.
-- & indicates either AND or AND THEN connecting two conditions. In the
- -- context of couverture we only permit AND THEN in the source in any
+ -- context of Couverture we only permit AND THEN in the source in any
-- case, so & can always be understood to be AND THEN.
-- | indicates either OR or OR ELSE connection two conditions. In the
- -- context of couverture we only permit OR ELSE in the source in any
+ -- context of Couverture we only permit OR ELSE in the source in any
-- case, so | can always be understood to be OR ELSE.
-- ^ indicates XOR connecting two conditions. In the context of
- -- couverture, we do not permit XOR, so this will never appear.
+ -- Couverture, we do not permit XOR, so this will never appear.
-- ! indicates NOT applied to the expression.
@@ -235,41 +268,34 @@ package SCOs is
-- The SCO_Table_Entry values appear as follows:
-- Statements
- -- C1 = 'S'
- -- C2 = ' '
+ -- C1 = 'S' for entry point, 's' otherwise
+ -- C2 = 't', 's', 'o', 'r', 'i', 'C', 'F', 'R', ' '
+ -- (type/subtype/object/renaming/instantiation/CASE/FOR/RETURN)
-- From = starting source location
-- To = ending source location
- -- Last = unused
-
- -- Exit
- -- C1 = 'T'
- -- C2 = ' '
- -- From = starting source location
- -- To = ending source location
- -- Last = unused
+ -- Last = False for all but the last entry, True for last entry
- -- Simple Decision
- -- C1 = 'I', 'E', 'W', 'X' (if/exit/while/expression)
- -- C2 = 'c', 't', or 'f'
- -- From = starting source location
- -- To = ending source location
- -- Last = True
+ -- Note: successive statements (possibly interspersed with entries of
+ -- other kinds, that are ignored for this purpose), starting with one
+ -- labeled with C1 = 'S', up to and including the first one labeled with
+ -- Last=True, indicate the sequence to be output for a sequence of
+ -- statements on a single CS line.
- -- Complex Decision
+ -- Decision
-- C1 = 'I', 'E', 'W', 'X' (if/exit/while/expression)
-- C2 = ' '
- -- From = No_Source_Location
+ -- From = location of IF/EXIT/WHILE token, No_Source_Location for X
-- To = No_Source_Location
- -- Last = False
+ -- Last = unused
-- Operator
-- C1 = '!', '^', '&', '|'
-- C2 = ' '
- -- From = No_Source_Location
+ -- From = location of NOT/XOR/AND/OR token
-- To = No_Source_Location
-- Last = False
- -- Element
+ -- Element (condition)
-- C1 = ' '
-- C2 = 'c', 't', or 'f' (condition/true/false)
-- From = starting source location
diff --git a/gcc/ada/sem.adb b/gcc/ada/sem.adb
index 071d38fdb45..caa73a0b82c 100644
--- a/gcc/ada/sem.adb
+++ b/gcc/ada/sem.adb
@@ -612,6 +612,7 @@ package body Sem is
N_SCIL_Dispatch_Table_Object_Init |
N_SCIL_Dispatch_Table_Tag_Init |
N_SCIL_Dispatching_Call |
+ N_SCIL_Membership_Test |
N_SCIL_Tag_Init =>
null;
diff --git a/gcc/ada/sem_case.adb b/gcc/ada/sem_case.adb
index 840214d2c64..da260f35c4a 100644
--- a/gcc/ada/sem_case.adb
+++ b/gcc/ada/sem_case.adb
@@ -239,8 +239,9 @@ package body Sem_Case is
" alternatives must cover base type", Expr, Expr);
else
- Error_Msg_N ("subtype of expression is not static," &
- " alternatives must cover base type!", Expr);
+ Error_Msg_N
+ ("subtype of expression is not static,"
+ & " alternatives must cover base type!", Expr);
end if;
-- Otherwise the expression is not static, even if the bounds of the
@@ -249,8 +250,8 @@ package body Sem_Case is
elsif not Is_Entity_Name (Expr) then
Error_Msg_N
- ("subtype of expression is not static, " &
- "alternatives must cover base type!", Expr);
+ ("subtype of expression is not static, "
+ & "alternatives must cover base type!", Expr);
end if;
end Explain_Non_Static_Bound;
diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb
index 170f261a36e..2f614080fdc 100644
--- a/gcc/ada/sem_ch10.adb
+++ b/gcc/ada/sem_ch10.adb
@@ -4000,13 +4000,44 @@ package body Sem_Ch10 is
-- If the item is a private with-clause on a child unit, the parent
-- may have been installed already, but the child unit must remain
- -- invisible until installed in a private part or body.
+ -- invisible until installed in a private part or body, unless there
+ -- is already a regular with_clause for it in the current unit.
elsif Private_Present (Item) then
Id := Entity (Name (Item));
if Is_Child_Unit (Id) then
- Set_Is_Visible_Child_Unit (Id, False);
+ declare
+ Clause : Node_Id;
+
+ function In_Context return Boolean;
+ -- Scan context of current unit, to check whether there is
+ -- a with_clause on the same unit as a private with-clause
+ -- on a parent, in which case child unit is visible.
+
+ function In_Context return Boolean is
+ begin
+ Clause :=
+ First (Context_Items (Cunit (Current_Sem_Unit)));
+ while Present (Clause) loop
+ if Nkind (Clause) = N_With_Clause
+ and then Comes_From_Source (Clause)
+ and then Is_Entity_Name (Name (Clause))
+ and then Entity (Name (Clause)) = Id
+ and then not Private_Present (Clause)
+ then
+ return True;
+ end if;
+
+ Next (Clause);
+ end loop;
+
+ return False;
+ end In_Context;
+
+ begin
+ Set_Is_Visible_Child_Unit (Id, In_Context);
+ end;
end if;
end if;
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 7dd9629da6a..1845e80916c 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -9725,11 +9725,12 @@ package body Sem_Ch3 is
New_T := Any_Type;
end if;
- -- If previous full declaration exists, or if a homograph is present,
- -- let Enter_Name handle it, either with an error, or with the removal
- -- of an overridden implicit subprogram.
+ -- If previous full declaration or a renaming declaration exists, or if
+ -- a homograph is present, let Enter_Name handle it, either with an
+ -- error or with the removal of an overridden implicit subprogram.
if Ekind (Prev) /= E_Constant
+ or else Nkind (Parent (Prev)) = N_Object_Renaming_Declaration
or else Present (Expression (Parent (Prev)))
or else Present (Full_View (Prev))
then
@@ -12418,6 +12419,24 @@ package body Sem_Ch3 is
Set_Convention (New_Subp, Convention (Parent_Subp));
end if;
+ -- Predefined controlled operations retain their name even if the parent
+ -- is hidden (see above), but they are not primitive operations if the
+ -- ancestor is not visible, for example if the parent is a private
+ -- extension completed with a controlled extension. Note that a full
+ -- type that is controlled can break privacy: the flag Is_Controlled is
+ -- set on both views of the type.
+
+ if Is_Controlled (Parent_Type)
+ and then
+ (Chars (Parent_Subp) = Name_Initialize
+ or else Chars (Parent_Subp) = Name_Adjust
+ or else Chars (Parent_Subp) = Name_Finalize)
+ and then Is_Hidden (Parent_Subp)
+ and then not Is_Visibly_Controlled (Parent_Type)
+ then
+ Set_Is_Hidden (New_Subp);
+ end if;
+
Set_Is_Imported (New_Subp, Is_Imported (Parent_Subp));
Set_Is_Exported (New_Subp, Is_Exported (Parent_Subp));
@@ -12493,8 +12512,8 @@ package body Sem_Ch3 is
then
if No (Actual_Subp) then
Set_Alias (New_Subp, Visible_Subp);
- Set_Is_Abstract_Subprogram
- (New_Subp, True);
+ Set_Is_Abstract_Subprogram (New_Subp, True);
+
else
-- If this is a derivation for an instance of a formal derived
-- type, abstractness comes from the primitive operation of the
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index 99c24a12a2e..899b1a05878 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -1251,7 +1251,7 @@ package body Sem_Ch4 is
Analyze_Expression (Else_Expr);
end if;
- if not Is_Overloaded (Then_Expr) then
+ if not Is_Overloaded (Then_Expr) then
Set_Etype (N, Etype (Then_Expr));
else
declare
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index 94ed69e2598..38b3b01a10b 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -1994,61 +1994,7 @@ package body Sem_Ch6 is
and then Comes_From_Source (N)
and then Is_Protected_Type (Current_Scope)
then
- declare
- Decl : Node_Id;
- Plist : List_Id;
- Formal : Entity_Id;
- New_Spec : Node_Id;
-
- begin
- Formal := First_Formal (Body_Id);
-
- -- The protected operation always has at least one formal, namely
- -- the object itself, but it is only placed in the parameter list
- -- if expansion is enabled.
-
- if Present (Formal)
- or else Expander_Active
- then
- Plist := Copy_Parameter_List (Body_Id);
- else
- Plist := No_List;
- end if;
-
- if Nkind (Body_Spec) = N_Procedure_Specification then
- New_Spec :=
- Make_Procedure_Specification (Loc,
- Defining_Unit_Name =>
- Make_Defining_Identifier (Sloc (Body_Id),
- Chars => Chars (Body_Id)),
- Parameter_Specifications => Plist);
- else
- New_Spec :=
- Make_Function_Specification (Loc,
- Defining_Unit_Name =>
- Make_Defining_Identifier (Sloc (Body_Id),
- Chars => Chars (Body_Id)),
- Parameter_Specifications => Plist,
- Result_Definition =>
- New_Occurrence_Of (Etype (Body_Id), Loc));
- end if;
-
- Decl :=
- Make_Subprogram_Declaration (Loc,
- Specification => New_Spec);
- Insert_Before (N, Decl);
- Spec_Id := Defining_Unit_Name (New_Spec);
-
- -- Indicate that the entity comes from source, to ensure that
- -- cross-reference information is properly generated. The body
- -- itself is rewritten during expansion, and the body entity will
- -- not appear in calls to the operation.
-
- Set_Comes_From_Source (Spec_Id, True);
- Analyze (Decl);
- Set_Has_Completion (Spec_Id);
- Set_Convention (Spec_Id, Convention_Protected);
- end;
+ Spec_Id := Build_Private_Protected_Declaration (N);
end if;
-- If a separate spec is present, then deal with freezing issues
@@ -2708,10 +2654,13 @@ package body Sem_Ch6 is
-- If the type of the first formal of the current subprogram is a
-- nongeneric tagged private type, mark the subprogram as being a
-- private primitive. Ditto if this is a function with controlling
- -- result, and the return type is currently private.
+ -- result, and the return type is currently private. In both cases,
+ -- the type of the controlling argument or result must be in the
+ -- current scope for the operation to be primitive.
if Has_Controlling_Result (Designator)
and then Is_Private_Type (Etype (Designator))
+ and then Scope (Etype (Designator)) = Current_Scope
and then not Is_Generic_Actual_Type (Etype (Designator))
then
Set_Is_Private_Primitive (Designator);
@@ -2723,6 +2672,7 @@ package body Sem_Ch6 is
begin
Set_Is_Private_Primitive (Designator,
Is_Tagged_Type (Formal_Typ)
+ and then Scope (Formal_Typ) = Current_Scope
and then Is_Private_Type (Formal_Typ)
and then not Is_Generic_Actual_Type (Formal_Typ));
end;
@@ -4454,7 +4404,9 @@ package body Sem_Ch6 is
end;
end if;
- if Present (Overridden_Subp) then
+ if Present (Overridden_Subp)
+ and then not Is_Hidden (Overridden_Subp)
+ then
if Must_Not_Override (Spec) then
Error_Msg_Sloc := Sloc (Overridden_Subp);
diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb
index 705f428716a..9c9da627ee0 100644
--- a/gcc/ada/sem_disp.adb
+++ b/gcc/ada/sem_disp.adb
@@ -48,7 +48,6 @@ with Sem_Eval; use Sem_Eval;
with Sem_Type; use Sem_Type;
with Sem_Util; use Sem_Util;
with Snames; use Snames;
-with Stand; use Stand;
with Sinfo; use Sinfo;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
@@ -673,27 +672,6 @@ package body Sem_Disp is
Has_Dispatching_Parent : Boolean := False;
Body_Is_Last_Primitive : Boolean := False;
- function Is_Visibly_Controlled (T : Entity_Id) return Boolean;
- -- Check whether T is derived from a visibly controlled type.
- -- This is true if the root type is declared in Ada.Finalization.
- -- If T is derived instead from a private type whose full view
- -- is controlled, an explicit Initialize/Adjust/Finalize subprogram
- -- does not override the inherited one.
-
- ---------------------------
- -- Is_Visibly_Controlled --
- ---------------------------
-
- function Is_Visibly_Controlled (T : Entity_Id) return Boolean is
- Root : constant Entity_Id := Root_Type (T);
- begin
- return Chars (Scope (Root)) = Name_Finalization
- and then Chars (Scope (Scope (Root))) = Name_Ada
- and then Scope (Scope (Scope (Root))) = Standard_Standard;
- end Is_Visibly_Controlled;
-
- -- Start of processing for Check_Dispatching_Operation
-
begin
if Ekind (Subp) /= E_Procedure and then Ekind (Subp) /= E_Function then
return;
@@ -1030,8 +1008,25 @@ package body Sem_Disp is
and then not Is_Visibly_Controlled (Tagged_Type)
then
Set_Is_Overriding_Operation (Subp, False);
- Error_Msg_NE
- ("operation does not override inherited&?", Subp, Subp);
+
+ -- If the subprogram specification carries an overriding
+ -- indicator, no need for the warning: it is either redundant,
+ -- or else an error will be reported.
+
+ if Nkind (Parent (Subp)) = N_Procedure_Specification
+ and then
+ (Must_Override (Parent (Subp))
+ or else Must_Not_Override (Parent (Subp)))
+ then
+ null;
+
+ -- Here we need the warning
+
+ else
+ Error_Msg_NE
+ ("operation does not override inherited&?", Subp, Subp);
+ end if;
+
else
Override_Dispatching_Operation (Tagged_Type, Old_Subp, Subp);
Set_Is_Overriding_Operation (Subp);
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 4d56d36ee39..daa08b4e95f 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -596,11 +596,13 @@ package body Sem_Prag is
procedure Process_Compile_Time_Warning_Or_Error;
-- Common processing for Compile_Time_Error and Compile_Time_Warning
- procedure Process_Convention (C : out Convention_Id; E : out Entity_Id);
+ procedure Process_Convention
+ (C : out Convention_Id;
+ Ent : out Entity_Id);
-- Common processing for Convention, Interface, Import and Export.
-- Checks first two arguments of pragma, and sets the appropriate
-- convention value in the specified entity or entities. On return
- -- C is the convention, E is the referenced entity.
+ -- C is the convention, Ent is the referenced entity.
procedure Process_Extended_Import_Export_Exception_Pragma
(Arg_Internal : Node_Id;
@@ -1152,6 +1154,14 @@ package body Sem_Prag is
String_Val : constant String_Id := Strval (Nam);
begin
+ -- We allow duplicated export names in CIL, as they are always
+ -- enclosed in a namespace that differentiates them, and overloaded
+ -- entities are supported by the VM.
+
+ if VM_Target = CLI_Target then
+ return;
+ end if;
+
-- We are only interested in the export case, and in the case of
-- generics, it is the instance, not the template, that is the
-- problem (the template will generate a warning in any case).
@@ -2347,10 +2357,11 @@ package body Sem_Prag is
------------------------
procedure Process_Convention
- (C : out Convention_Id;
- E : out Entity_Id)
+ (C : out Convention_Id;
+ Ent : out Entity_Id)
is
Id : Node_Id;
+ E : Entity_Id;
E1 : Entity_Id;
Cname : Name_Id;
Comp_Unit : Unit_Number_Type;
@@ -2482,6 +2493,10 @@ package body Sem_Prag is
E := Entity (Id);
+ -- Set entity to return
+
+ Ent := E;
+
-- Go to renamed subprogram if present, since convention applies to
-- the actual renamed entity, not to the renaming entity. If the
-- subprogram is inherited, go to parent subprogram.
@@ -2504,6 +2519,10 @@ package body Sem_Prag is
and then Scope (E) = Scope (Alias (E))
then
E := Alias (E);
+
+ -- Return the parent subprogram the entity was inherited from
+
+ Ent := E;
end if;
end if;
@@ -2617,7 +2636,9 @@ package body Sem_Prag is
Generate_Reference (E, Id, 'b');
end if;
- E1 := E;
+ -- Loop through the homonyms of the pragma argument's entity
+
+ E1 := Ent;
loop
E1 := Homonym (E1);
exit when No (E1) or else Scope (E1) /= Current_Scope;
@@ -2642,7 +2663,7 @@ package body Sem_Prag is
Set_Convention_From_Pragma (E1);
if Prag_Id = Pragma_Import then
- Generate_Reference (E, Id, 'b');
+ Generate_Reference (E1, Id, 'b');
end if;
end if;
end loop;
@@ -3459,6 +3480,8 @@ package body Sem_Prag is
else
Set_Imported (Def_Id);
+ -- Reject an Import applied to an abstract subprogram
+
if Is_Subprogram (Def_Id)
and then Is_Abstract_Subprogram (Def_Id)
then
@@ -5212,9 +5235,13 @@ package body Sem_Prag is
-- Annotate --
--------------
- -- pragma Annotate (IDENTIFIER {, ARG});
+ -- pragma Annotate (IDENTIFIER [, IDENTIFIER {, ARG}]);
-- ARG ::= NAME | EXPRESSION
+ -- The first two arguments are by convention intended to refer to an
+ -- external tool and a tool-specific function. These arguments are
+ -- not analyzed.
+
when Pragma_Annotate => Annotate : begin
GNAT_Pragma;
Check_At_Least_N_Arguments (1);
@@ -5225,26 +5252,33 @@ package body Sem_Prag is
Exp : Node_Id;
begin
- Arg := Arg2;
- while Present (Arg) loop
- Exp := Expression (Arg);
- Analyze (Exp);
+ -- Second unanalyzed parameter is optional
- if Is_Entity_Name (Exp) then
- null;
+ if No (Arg2) then
+ null;
+ else
+ Arg := Next (Arg2);
+ while Present (Arg) loop
+ Exp := Expression (Arg);
+ Analyze (Exp);
- elsif Nkind (Exp) = N_String_Literal then
- Resolve (Exp, Standard_String);
+ if Is_Entity_Name (Exp) then
+ null;
- elsif Is_Overloaded (Exp) then
- Error_Pragma_Arg ("ambiguous argument for pragma%", Exp);
+ elsif Nkind (Exp) = N_String_Literal then
+ Resolve (Exp, Standard_String);
- else
- Resolve (Exp);
- end if;
+ elsif Is_Overloaded (Exp) then
+ Error_Pragma_Arg
+ ("ambiguous argument for pragma%", Exp);
- Next (Arg);
- end loop;
+ else
+ Resolve (Exp);
+ end if;
+
+ Next (Arg);
+ end loop;
+ end if;
end;
end Annotate;
@@ -10658,8 +10692,24 @@ package body Sem_Prag is
when Pragma_Reviewable =>
Check_Ada_83_Warning;
Check_Arg_Count (0);
+
+ -- Call dummy debugging function rv. This is done to assist front
+ -- end debugging. By placing a Reviewable pragma in the source
+ -- program, a breakpoint on rv catches this place in the source,
+ -- allowing convenient stepping to the point of interest.
+
rv;
+ --------------------------
+ -- Short_Circuit_And_Or --
+ --------------------------
+
+ when Pragma_Short_Circuit_And_Or =>
+ GNAT_Pragma;
+ Check_Arg_Count (0);
+ Check_Valid_Configuration_Pragma;
+ Short_Circuit_And_Or := True;
+
-------------------
-- Share_Generic --
-------------------
@@ -11979,6 +12029,14 @@ package body Sem_Prag is
Check_At_Least_N_Arguments (1);
Check_No_Identifiers;
+ -- If debug flag -gnatd.i is set, pragma is ignored
+
+ if Debug_Flag_Dot_I then
+ return;
+ end if;
+
+ -- Process various forms of the pragma
+
declare
Argx : constant Node_Id := Get_Pragma_Arg (Arg1);
@@ -12522,6 +12580,7 @@ package body Sem_Prag is
Pragma_Restriction_Warnings => -1,
Pragma_Restrictions => -1,
Pragma_Reviewable => -1,
+ Pragma_Short_Circuit_And_Or => -1,
Pragma_Share_Generic => -1,
Pragma_Shared => -1,
Pragma_Shared_Passive => -1,
diff --git a/gcc/ada/sem_scil.adb b/gcc/ada/sem_scil.adb
index cd4e66be554..5adf803fc70 100644
--- a/gcc/ada/sem_scil.adb
+++ b/gcc/ada/sem_scil.adb
@@ -74,7 +74,9 @@ package body Sem_SCIL is
-- Type conversions may involve dispatching calls to functions whose
-- associated SCIL dispatching node needs adjustment.
- elsif Nkind (Old_Node) = N_Type_Conversion then
+ elsif Nkind_In (Old_Node, N_Type_Conversion,
+ N_Unchecked_Type_Conversion)
+ then
null;
-- Relocated subprogram call
@@ -101,15 +103,58 @@ package body Sem_SCIL is
-- Check_SCIL_Node --
---------------------
- -- Is this a good name for the function, given it only deals with
- -- N_SCIL_Dispatching_Call case ???
-
function Check_SCIL_Node (N : Node_Id) return Traverse_Result is
Ctrl_Tag : Node_Id;
Ctrl_Typ : Entity_Id;
begin
- if Nkind (N) = N_SCIL_Dispatching_Call then
+ if Nkind (N) = N_SCIL_Membership_Test then
+
+ -- Check contents of the boolean expression associated with the
+ -- membership test.
+
+ pragma Assert (Nkind (SCIL_Related_Node (N)) = N_Identifier
+ and then Etype (SCIL_Related_Node (N)) = Standard_Boolean);
+
+ -- Check the entity identifier of the associated tagged type (that
+ -- is, in testing for membership in T'Class, the entity id of the
+ -- specific type T).
+
+ -- Note: When the SCIL node is generated the private and full-view
+ -- of the tagged types may have been swapped and hence the node
+ -- referenced by attribute SCIL_Entity may be the private view.
+ -- Therefore, in order to uniformily locate the full-view we use
+ -- attribute Underlying_Type.
+
+ pragma Assert (Is_Tagged_Type (Underlying_Type (SCIL_Entity (N))));
+
+ -- Interface types are unsupported
+
+ pragma Assert (not Is_Interface (Underlying_Type (SCIL_Entity (N))));
+
+ -- Check the decoration of the expression that denotes the tag value
+ -- being tested
+
+ Ctrl_Tag := SCIL_Tag_Value (N);
+
+ case Nkind (Ctrl_Tag) is
+
+ -- For class-wide membership tests the SCIL tag value is the tag
+ -- of the tested object (i.e. Obj.Tag).
+
+ when N_Selected_Component =>
+ pragma Assert (Etype (Ctrl_Tag) = RTE (RE_Tag));
+ null;
+
+ when others =>
+ pragma Assert (False);
+ null;
+
+ end case;
+
+ return Skip;
+
+ elsif Nkind (N) = N_SCIL_Dispatching_Call then
Ctrl_Tag := SCIL_Controlling_Tag (N);
-- SCIL_Related_Node of SCIL dispatching call nodes MUST reference
@@ -452,6 +497,7 @@ package body Sem_SCIL is
N_SCIL_Dispatch_Table_Object_Init |
N_SCIL_Dispatch_Table_Tag_Init |
N_SCIL_Dispatching_Call |
+ N_SCIL_Membership_Test |
N_SCIL_Tag_Init
=>
pragma Assert (False);
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index cbcbc16588e..e56066b7d4d 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -7040,22 +7040,71 @@ package body Sem_Util is
function Is_Value_Type (T : Entity_Id) return Boolean is
begin
return VM_Target = CLI_Target
+ and then Nkind (T) in N_Has_Chars
and then Chars (T) /= No_Name
and then Get_Name_String (Chars (T)) = "valuetype";
end Is_Value_Type;
-----------------
+ -- Is_Delegate --
+ -----------------
+
+ function Is_Delegate (T : Entity_Id) return Boolean is
+ Desig_Type : Entity_Id;
+
+ begin
+ if VM_Target /= CLI_Target then
+ return False;
+ end if;
+
+ -- Access-to-subprograms are delegates in CIL
+
+ if Ekind (T) = E_Access_Subprogram_Type then
+ return True;
+ end if;
+
+ if Ekind (T) not in Access_Kind then
+
+ -- A delegate is a managed pointer. If no designated type is defined
+ -- it means that it's not a delegate.
+
+ return False;
+ end if;
+
+ Desig_Type := Etype (Directly_Designated_Type (T));
+
+ if not Is_Tagged_Type (Desig_Type) then
+ return False;
+ end if;
+
+ -- Test if the type is inherited from [mscorlib]System.Delegate
+
+ while Etype (Desig_Type) /= Desig_Type loop
+ if Chars (Scope (Desig_Type)) /= No_Name
+ and then Is_Imported (Scope (Desig_Type))
+ and then Get_Name_String (Chars (Scope (Desig_Type))) = "delegate"
+ then
+ return True;
+ end if;
+
+ Desig_Type := Etype (Desig_Type);
+ end loop;
+
+ return False;
+ end Is_Delegate;
+
+ -----------------
-- Is_Variable --
-----------------
function Is_Variable (N : Node_Id) return Boolean is
Orig_Node : constant Node_Id := Original_Node (N);
- -- We do the test on the original node, since this is basically a
- -- test of syntactic categories, so it must not be disturbed by
- -- whatever rewriting might have occurred. For example, an aggregate,
- -- which is certainly NOT a variable, could be turned into a variable
- -- by expansion.
+ -- We do the test on the original node, since this is basically a test
+ -- of syntactic categories, so it must not be disturbed by whatever
+ -- rewriting might have occurred. For example, an aggregate, which is
+ -- certainly NOT a variable, could be turned into a variable by
+ -- expansion.
function In_Protected_Function (E : Entity_Id) return Boolean;
-- Within a protected function, the private components of the
@@ -7238,6 +7287,18 @@ package body Sem_Util is
end if;
end Is_Variable;
+ ---------------------------
+ -- Is_Visibly_Controlled --
+ ---------------------------
+
+ function Is_Visibly_Controlled (T : Entity_Id) return Boolean is
+ Root : constant Entity_Id := Root_Type (T);
+ begin
+ return Chars (Scope (Root)) = Name_Finalization
+ and then Chars (Scope (Scope (Root))) = Name_Ada
+ and then Scope (Scope (Scope (Root))) = Standard_Standard;
+ end Is_Visibly_Controlled;
+
------------------------
-- Is_Volatile_Object --
------------------------
@@ -11319,7 +11380,15 @@ package body Sem_Util is
L : constant Node_Id := Left_Opnd (Op);
R : constant Node_Id := Right_Opnd (Op);
begin
- if Etype (L) = Found_Type
+ -- The case for the message is when the left operand of the
+ -- comparison is the same modular type, or when it is an
+ -- integer literal (or other universal integer expression),
+ -- which would have been typed as the modular type if the
+ -- parens had been there.
+
+ if (Etype (L) = Found_Type
+ or else
+ Etype (L) = Universal_Integer)
and then Is_Integer_Type (Etype (R))
then
Error_Msg_N
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index 623a72b2782..ed36cf8f3d7 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -210,10 +210,10 @@ package Sem_Util is
-- of Old is set and Old has no yet been Frozen (i.e. Is_Frozen is false);
function Copy_Parameter_List (Subp_Id : Entity_Id) return List_Id;
- -- Utility to create a parameter profile for a new subprogram spec,
- -- when the subprogram has a body that acts as spec. This is done for
- -- some cases of inlining, and for private protected ops. Also used
- -- to create bodies for stubbed subprograms.
+ -- Utility to create a parameter profile for a new subprogram spec, when
+ -- the subprogram has a body that acts as spec. This is done for some cases
+ -- of inlining, and for private protected ops. Also used to create bodies
+ -- for stubbed subprograms.
function Current_Entity (N : Node_Id) return Entity_Id;
-- Find the currently visible definition for a given identifier, that is to
@@ -230,9 +230,9 @@ package Sem_Util is
function Current_Subprogram return Entity_Id;
-- Returns current enclosing subprogram. If Current_Scope is a subprogram,
- -- then that is what is returned, otherwise the Enclosing_Subprogram of
- -- the Current_Scope is returned. The returned value is Empty if this
- -- is called from a library package which is not within any subprogram.
+ -- then that is what is returned, otherwise the Enclosing_Subprogram of the
+ -- Current_Scope is returned. The returned value is Empty if this is called
+ -- from a library package which is not within any subprogram.
function Defining_Entity (N : Node_Id) return Entity_Id;
-- Given a declaration N, returns the associated defining entity. If
@@ -619,10 +619,9 @@ package Sem_Util is
-- corresponding private part must not.
procedure Insert_Explicit_Dereference (N : Node_Id);
- -- In a context that requires a composite or subprogram type and
- -- where a prefix is an access type, rewrite the access type node
- -- N (which is the prefix, e.g. of an indexed component) as an
- -- explicit dereference.
+ -- In a context that requires a composite or subprogram type and where a
+ -- prefix is an access type, rewrite the access type node N (which is the
+ -- prefix, e.g. of an indexed component) as an explicit dereference.
procedure Inspect_Deferred_Constant_Completion (Decls : List_Id);
-- Examine all deferred constants in the declaration list Decls and check
@@ -630,13 +629,12 @@ package Sem_Util is
-- Import pragma. Emit the error message if that is not the case.
function Is_AAMP_Float (E : Entity_Id) return Boolean;
- -- Defined for all type entities. Returns True only for the base type
- -- of float types with AAMP format. The particular format is determined
- -- by the Digits_Value value which is 6 for the 32-bit floating point type,
- -- or 9 for the 48-bit type. This is not an attribute function (like
- -- VAX_Float) in order to not use up an extra flag and to prevent
- -- the dependency of Einfo on Targparm which would be required for a
- -- synthesized attribute.
+ -- Defined for all type entities. Returns True only for the base type of
+ -- float types with AAMP format. The particular format is determined by the
+ -- Digits_Value value which is 6 for the 32-bit floating point type, or 9
+ -- for the 48-bit type. This is not an attribute function (like VAX_Float)
+ -- in order to not use up an extra flag and to prevent the dependency of
+ -- Einfo on Targparm which would be required for a synthesized attribute.
function Is_Actual_Out_Parameter (N : Node_Id) return Boolean;
-- Determines if N is an actual parameter of out mode in a subprogram call
@@ -677,10 +675,10 @@ package Sem_Util is
-- False. The nodes passed to this function are assumed to denote objects.
function Is_Dereferenced (N : Node_Id) return Boolean;
- -- N is a subexpression node of an access type. This function returns
- -- true if N appears as the prefix of a node that does a dereference
- -- of the access value (selected/indexed component, explicit dereference
- -- or a slice), and false otherwise.
+ -- N is a subexpression node of an access type. This function returns true
+ -- if N appears as the prefix of a node that does a dereference of the
+ -- access value (selected/indexed component, explicit dereference or a
+ -- slice), and false otherwise.
function Is_Descendent_Of (T1 : Entity_Id; T2 : Entity_Id) return Boolean;
-- Returns True if type T1 is a descendent of type T2, and false otherwise.
@@ -721,8 +719,8 @@ package Sem_Util is
-- i.e. a library unit or an entity declared in a library package.
function Is_Local_Variable_Reference (Expr : Node_Id) return Boolean;
- -- Determines whether Expr is a reference to a variable or IN OUT
- -- mode parameter of the current enclosing subprogram.
+ -- Determines whether Expr is a reference to a variable or IN OUT mode
+ -- parameter of the current enclosing subprogram.
-- Why are OUT parameters not considered here ???
function Is_Object_Reference (N : Node_Id) return Boolean;
@@ -737,12 +735,11 @@ package Sem_Util is
-- target are considered view conversions and hence variables.
function Is_Partially_Initialized_Type (Typ : Entity_Id) return Boolean;
- -- Typ is a type entity. This function returns true if this type is
- -- partly initialized, meaning that an object of the type is at least
- -- partly initialized (in particular in the record case, that at least
- -- one component has an initialization expression). Note that
- -- initialization resulting from the use of pragma Normalized_Scalars does
- -- not count.
+ -- Typ is a type entity. This function returns true if this type is partly
+ -- initialized, meaning that an object of the type is at least partly
+ -- initialized (in particular in the record case, that at least one
+ -- component has an initialization expression). Note that initialization
+ -- resulting from the use of pragma Normalized_Scalars does not count.
function Is_Potentially_Persistent_Type (T : Entity_Id) return Boolean;
-- Determines if type T is a potentially persistent type. A potentially
@@ -799,24 +796,35 @@ package Sem_Util is
function Is_Value_Type (T : Entity_Id) return Boolean;
-- Returns true if type T represents a value type. This is only relevant to
- -- CIL, will always return false for other targets.
- -- What is a "value type", since this is not an Ada term, it should be
- -- defined here ???
+ -- CIL, will always return false for other targets. A value type is a CIL
+ -- object that is accessed directly, as opposed to the other CIL objects
+ -- that are accessed through managed pointers.
+
+ function Is_Delegate (T : Entity_Id) return Boolean;
+ -- Returns true if type T represents a delegate. A Delegate is the CIL
+ -- object used to represent access-to-subprogram types. This is only
+ -- relevant to CIL, will always return false for other targets.
function Is_Variable (N : Node_Id) return Boolean;
- -- Determines if the tree referenced by N represents a variable, i.e.
- -- can appear on the left side of an assignment. There is one situation,
- -- namely formal parameters, in which non-tagged type conversions are
- -- also considered variables, but Is_Variable returns False for such
- -- cases, since it has no knowledge of the context. Note that this is
- -- the point at which Assignment_OK is checked, and True is returned
- -- for any tree thus marked.
+ -- Determines if the tree referenced by N represents a variable, i.e. can
+ -- appear on the left side of an assignment. There is one situation (formal
+ -- parameters) in which non-tagged type conversions are also considered
+ -- variables, but Is_Variable returns False for such cases, since it has
+ -- no knowledge of the context. Note that this is the point at which
+ -- Assignment_OK is checked, and True is returned for any tree thus marked.
+
+ function Is_Visibly_Controlled (T : Entity_Id) return Boolean;
+ -- Check whether T is derived from a visibly controlled type. This is true
+ -- if the root type is declared in Ada.Finalization. If T is derived
+ -- instead from a private type whose full view is controlled, an explicit
+ -- Initialize/Adjust/Finalize subprogram does not override the inherited
+ -- one.
function Is_Volatile_Object (N : Node_Id) return Boolean;
- -- Determines if the given node denotes an volatile object in the sense
- -- of the legality checks described in RM C.6(12). Note that the test
- -- here is for something actually declared as volatile, not for an object
- -- that gets treated as volatile (see Einfo.Treat_As_Volatile).
+ -- Determines if the given node denotes an volatile object in the sense of
+ -- the legality checks described in RM C.6(12). Note that the test here is
+ -- for something actually declared as volatile, not for an object that gets
+ -- treated as volatile (see Einfo.Treat_As_Volatile).
procedure Kill_Current_Values (Last_Assignment_Only : Boolean := False);
-- This procedure is called to clear all constant indications from all
@@ -854,8 +862,8 @@ package Sem_Util is
procedure Kill_Size_Check_Code (E : Entity_Id);
-- Called when an address clause or pragma Import is applied to an entity.
-- If the entity is a variable or a constant, and size check code is
- -- present, this size check code is killed, since the object will not
- -- be allocated by the program.
+ -- present, this size check code is killed, since the object will not be
+ -- allocated by the program.
function Known_To_Be_Assigned (N : Node_Id) return Boolean;
-- The node N is an entity reference. This function determines whether the
diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb
index abfdf1ff668..580ba9aedc0 100644
--- a/gcc/ada/sem_warn.adb
+++ b/gcc/ada/sem_warn.adb
@@ -2992,8 +2992,10 @@ package body Sem_Warn is
Warn_On_Object_Renames_Function := True;
Warn_On_Obsolescent_Feature := True;
Warn_On_Overlap := True;
+ Warn_On_Parameter_Order := True;
Warn_On_Questionable_Missing_Parens := True;
Warn_On_Redundant_Constructs := True;
+ Warn_On_Reverse_Bit_Order := True;
Warn_On_Unchecked_Conversion := True;
Warn_On_Unrecognized_Pragma := True;
Warn_On_Unrepped_Components := True;
@@ -3032,6 +3034,12 @@ package body Sem_Warn is
when 'R' =>
Warn_On_Object_Renames_Function := False;
+ when 'v' =>
+ Warn_On_Reverse_Bit_Order := True;
+
+ when 'V' =>
+ Warn_On_Reverse_Bit_Order := False;
+
when 'w' =>
Warn_On_Warnings_Off := True;
@@ -3084,6 +3092,7 @@ package body Sem_Warn is
Warn_On_Obsolescent_Feature := True;
Warn_On_Questionable_Missing_Parens := True;
Warn_On_Redundant_Constructs := True;
+ Warn_On_Reverse_Bit_Order := False;
Warn_On_Object_Renames_Function := True;
Warn_On_Unchecked_Conversion := True;
Warn_On_Unrecognized_Pragma := True;
@@ -3120,11 +3129,13 @@ package body Sem_Warn is
Warn_On_Parameter_Order := True;
Warn_On_Questionable_Missing_Parens := True;
Warn_On_Redundant_Constructs := True;
+ Warn_On_Reverse_Bit_Order := True;
Warn_On_Unchecked_Conversion := True;
Warn_On_Unrecognized_Pragma := True;
Warn_On_Unrepped_Components := True;
when 'A' =>
+ Address_Clause_Overlay_Warnings := False;
Check_Unreferenced := False;
Check_Unreferenced_Formals := False;
Check_Withs := False;
@@ -3133,6 +3144,7 @@ package body Sem_Warn is
Implementation_Unit_Warnings := False;
Ineffective_Inline_Warnings := False;
Warn_On_Ada_2005_Compatibility := False;
+ Warn_On_All_Unread_Out_Parameters := False;
Warn_On_Assertion_Failure := False;
Warn_On_Assumed_Low_Bound := False;
Warn_On_Bad_Fixed_Value := False;
@@ -3145,13 +3157,13 @@ package body Sem_Warn is
Warn_On_Modified_Unread := False;
Warn_On_No_Value_Assigned := False;
Warn_On_Non_Local_Exception := False;
+ Warn_On_Object_Renames_Function := False;
Warn_On_Obsolescent_Feature := False;
Warn_On_Overlap := False;
- Warn_On_All_Unread_Out_Parameters := False;
Warn_On_Parameter_Order := False;
Warn_On_Questionable_Missing_Parens := False;
Warn_On_Redundant_Constructs := False;
- Warn_On_Object_Renames_Function := False;
+ Warn_On_Reverse_Bit_Order := False;
Warn_On_Unchecked_Conversion := False;
Warn_On_Unrecognized_Pragma := False;
Warn_On_Unrepped_Components := False;
diff --git a/gcc/ada/sinfo.adb b/gcc/ada/sinfo.adb
index dd4aaafce9a..f4c171cebf7 100644
--- a/gcc/ada/sinfo.adb
+++ b/gcc/ada/sinfo.adb
@@ -1481,6 +1481,14 @@ package body Sinfo is
return Flag11 (N);
end Has_Wide_Character;
+ function Has_Wide_Wide_Character
+ (N : Node_Id) return Boolean is
+ begin
+ pragma Assert (False
+ or else NT (N).Nkind = N_String_Literal);
+ return Flag13 (N);
+ end Has_Wide_Wide_Character;
+
function Hidden_By_Use_Clause
(N : Node_Id) return Elist_Id is
begin
@@ -1588,7 +1596,7 @@ package body Sinfo is
begin
pragma Assert (False
or else NT (N).Nkind = N_Parameter_Association);
- return Flag12 (N);
+ return Flag13 (N);
end Is_Accessibility_Actual;
function Is_Asynchronous_Call_Block
@@ -2556,6 +2564,7 @@ package body Sinfo is
or else NT (N).Nkind = N_SCIL_Dispatch_Table_Object_Init
or else NT (N).Nkind = N_SCIL_Dispatch_Table_Tag_Init
or else NT (N).Nkind = N_SCIL_Dispatching_Call
+ or else NT (N).Nkind = N_SCIL_Membership_Test
or else NT (N).Nkind = N_SCIL_Tag_Init);
return Node4 (N);
end SCIL_Entity;
@@ -2567,10 +2576,19 @@ package body Sinfo is
or else NT (N).Nkind = N_SCIL_Dispatch_Table_Object_Init
or else NT (N).Nkind = N_SCIL_Dispatch_Table_Tag_Init
or else NT (N).Nkind = N_SCIL_Dispatching_Call
+ or else NT (N).Nkind = N_SCIL_Membership_Test
or else NT (N).Nkind = N_SCIL_Tag_Init);
return Node1 (N);
end SCIL_Related_Node;
+ function SCIL_Tag_Value
+ (N : Node_Id) return Node_Id is
+ begin
+ pragma Assert (False
+ or else NT (N).Nkind = N_SCIL_Membership_Test);
+ return Node5 (N);
+ end SCIL_Tag_Value;
+
function SCIL_Target_Prim
(N : Node_Id) return Node_Id is
begin
@@ -4341,6 +4359,14 @@ package body Sinfo is
Set_Flag11 (N, Val);
end Set_Has_Wide_Character;
+ procedure Set_Has_Wide_Wide_Character
+ (N : Node_Id; Val : Boolean := True) is
+ begin
+ pragma Assert (False
+ or else NT (N).Nkind = N_String_Literal);
+ Set_Flag13 (N, Val);
+ end Set_Has_Wide_Wide_Character;
+
procedure Set_Hidden_By_Use_Clause
(N : Node_Id; Val : Elist_Id) is
begin
@@ -4448,7 +4474,7 @@ package body Sinfo is
begin
pragma Assert (False
or else NT (N).Nkind = N_Parameter_Association);
- Set_Flag12 (N, Val);
+ Set_Flag13 (N, Val);
end Set_Is_Accessibility_Actual;
procedure Set_Is_Asynchronous_Call_Block
@@ -5416,6 +5442,7 @@ package body Sinfo is
or else NT (N).Nkind = N_SCIL_Dispatch_Table_Object_Init
or else NT (N).Nkind = N_SCIL_Dispatch_Table_Tag_Init
or else NT (N).Nkind = N_SCIL_Dispatching_Call
+ or else NT (N).Nkind = N_SCIL_Membership_Test
or else NT (N).Nkind = N_SCIL_Tag_Init);
Set_Node4 (N, Val); -- semantic field, no parent set
end Set_SCIL_Entity;
@@ -5427,10 +5454,19 @@ package body Sinfo is
or else NT (N).Nkind = N_SCIL_Dispatch_Table_Object_Init
or else NT (N).Nkind = N_SCIL_Dispatch_Table_Tag_Init
or else NT (N).Nkind = N_SCIL_Dispatching_Call
+ or else NT (N).Nkind = N_SCIL_Membership_Test
or else NT (N).Nkind = N_SCIL_Tag_Init);
Set_Node1 (N, Val); -- semantic field, no parent set
end Set_SCIL_Related_Node;
+ procedure Set_SCIL_Tag_Value
+ (N : Node_Id; Val : Node_Id) is
+ begin
+ pragma Assert (False
+ or else NT (N).Nkind = N_SCIL_Membership_Test);
+ Set_Node5 (N, Val); -- semantic field, no parent set
+ end Set_SCIL_Tag_Value;
+
procedure Set_SCIL_Target_Prim
(N : Node_Id; Val : Node_Id) is
begin
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index 2e666c49a64..bb6012904a9 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -462,10 +462,18 @@ package Sinfo is
-- reasons.
-- Comes_From_Source (Flag2)
- -- This flag is on for any nodes built by the scanner or parser from the
- -- source program, and off for any nodes built by the analyzer or
- -- expander. It indicates that a node comes from the original source.
- -- This flag is defined in Atree.
+ -- This flag is set if the node comes directly from an explicit construct
+ -- in the source. It is normally on for any nodes built by the scanner or
+ -- parser from the source program, with the exception that in a few cases
+ -- the parser adds nodes to normalize the representation (in particular
+ -- a null statement is added to a package body if there is no begin/end
+ -- initialization section.
+ --
+ -- Most nodes inserted by the analyzer or expander are not considered
+ -- as coming from source, so the flag is off for such nodes. In a few
+ -- cases, the expander constructs nodes closely equivalent to nodes
+ -- from the source program (e.g. the allocator built for build-in-place
+ -- case), and the Comes_From_Source flag is deliberately set.
-- Error_Posted (Flag3)
-- This flag is used to avoid multiple error messages being posted on or
@@ -1149,7 +1157,13 @@ package Sinfo is
-- Has_Wide_Character (Flag11-Sem)
-- Present in string literals, set if any wide character (i.e. character
- -- code outside the Character range) appears in the string.
+ -- code outside the Character range but within Wide_Character range)
+ -- appears in the string. Used to implement pragma preference rules.
+
+ -- Has_Wide_Wide_Character (Flag13-Sem)
+ -- Present in string literals, set if any wide character (i.e. character
+ -- code outside the Wide_Character range) appears in the string. Used to
+ -- implement pragma preference rules.
-- Hidden_By_Use_Clause (Elist4-Sem)
-- An entity list present in use clauses that appear within
@@ -1608,6 +1622,10 @@ package Sinfo is
-- Present in N_SCIL_Dispatching_Call nodes. Used to reference the
-- controlling tag of a dispatching call.
+ -- SCIL_Tag_Value (Node5-Sem)
+ -- Present in N_SCIL_Membership_Test nodes. Used to reference the tag
+ -- value that is being tested.
+
-- SCIL_Target_Prim (Node2-Sem)
-- Present in N_SCIL_Dispatching_Call nodes. Used to reference the tagged
-- type primitive associated with the SCIL node.
@@ -1933,6 +1951,7 @@ package Sinfo is
-- Sloc points to literal
-- Strval (Str3) contains Id of string value
-- Has_Wide_Character (Flag11-Sem)
+ -- Has_Wide_Wide_Character (Flag13-Sem)
-- Is_Folded_In_Parser (Flag4)
-- plus fields for expression
@@ -4457,7 +4476,7 @@ package Sinfo is
-- Selector_Name (Node2) (always non-Empty)
-- Explicit_Actual_Parameter (Node3)
-- Next_Named_Actual (Node4-Sem)
- -- Is_Accessibility_Actual (Flag12-Sem)
+ -- Is_Accessibility_Actual (Flag13-Sem)
---------------------------
-- 6.4 Actual Parameter --
@@ -6886,6 +6905,12 @@ package Sinfo is
-- SCIL_Entity (Node4-Sem)
-- SCIL_Controlling_Tag (Node5-Sem)
+ -- N_SCIL_Membership_Test
+ -- Sloc references the node of a membership test
+ -- SCIL_Related_Node (Node1-Sem)
+ -- SCIL_Tag_Value (Node5-Sem)
+ -- SCIL_Entity (Node4-Sem)
+
-- N_SCIL_Tag_Init
-- Sloc references the node of a tag component initialization
-- SCIL_Related_Node (Node1-Sem)
@@ -7333,6 +7358,7 @@ package Sinfo is
N_SCIL_Dispatch_Table_Object_Init,
N_SCIL_Dispatch_Table_Tag_Init,
N_SCIL_Dispatching_Call,
+ N_SCIL_Membership_Test,
N_SCIL_Tag_Init,
-- Other nodes (not part of any subtype class)
@@ -8048,6 +8074,9 @@ package Sinfo is
function Has_Wide_Character
(N : Node_Id) return Boolean; -- Flag11
+ function Has_Wide_Wide_Character
+ (N : Node_Id) return Boolean; -- Flag13
+
function Hidden_By_Use_Clause
(N : Node_Id) return Elist_Id; -- Elist4
@@ -8079,7 +8108,7 @@ package Sinfo is
(N : Node_Id) return Uint; -- Uint3
function Is_Accessibility_Actual
- (N : Node_Id) return Boolean; -- Flag12
+ (N : Node_Id) return Boolean; -- Flag13
function Is_Asynchronous_Call_Block
(N : Node_Id) return Boolean; -- Flag7
@@ -8390,6 +8419,9 @@ package Sinfo is
function SCIL_Related_Node
(N : Node_Id) return Node_Id; -- Node1
+ function SCIL_Tag_Value
+ (N : Node_Id) return Node_Id; -- Node5
+
function SCIL_Target_Prim
(N : Node_Id) return Node_Id; -- Node2
@@ -8960,6 +8992,9 @@ package Sinfo is
procedure Set_Has_Wide_Character
(N : Node_Id; Val : Boolean := True); -- Flag11
+ procedure Set_Has_Wide_Wide_Character
+ (N : Node_Id; Val : Boolean := True); -- Flag13
+
procedure Set_Hidden_By_Use_Clause
(N : Node_Id; Val : Elist_Id); -- Elist4
@@ -8991,7 +9026,7 @@ package Sinfo is
(N : Node_Id; Val : Uint); -- Uint3
procedure Set_Is_Accessibility_Actual
- (N : Node_Id; Val : Boolean := True); -- Flag12
+ (N : Node_Id; Val : Boolean := True); -- Flag13
procedure Set_Is_Asynchronous_Call_Block
(N : Node_Id; Val : Boolean := True); -- Flag7
@@ -9302,6 +9337,9 @@ package Sinfo is
procedure Set_SCIL_Related_Node
(N : Node_Id; Val : Node_Id); -- Node1
+ procedure Set_SCIL_Tag_Value
+ (N : Node_Id; Val : Node_Id); -- Node5
+
procedure Set_SCIL_Target_Prim
(N : Node_Id; Val : Node_Id); -- Node2
@@ -11056,6 +11094,13 @@ package Sinfo is
4 => False, -- SCIL_Entity (Node4-Sem)
5 => False), -- SCIL_Controlling_Tag (Node5-Sem)
+ N_SCIL_Membership_Test =>
+ (1 => False, -- SCIL_Related_Node (Node1-Sem)
+ 2 => False, -- unused
+ 3 => False, -- unused
+ 4 => False, -- SCIL_Entity (Node4-Sem)
+ 5 => False), -- SCIL_Tag_Value (Node5-Sem)
+
N_SCIL_Tag_Init =>
(1 => False, -- SCIL_Related_Node (Node1-Sem)
2 => False, -- unused
@@ -11250,6 +11295,7 @@ package Sinfo is
pragma Inline (Has_Task_Info_Pragma);
pragma Inline (Has_Task_Name_Pragma);
pragma Inline (Has_Wide_Character);
+ pragma Inline (Has_Wide_Wide_Character);
pragma Inline (Hidden_By_Use_Clause);
pragma Inline (High_Bound);
pragma Inline (Identifier);
@@ -11364,6 +11410,7 @@ package Sinfo is
pragma Inline (SCIL_Controlling_Tag);
pragma Inline (SCIL_Entity);
pragma Inline (SCIL_Related_Node);
+ pragma Inline (SCIL_Tag_Value);
pragma Inline (SCIL_Target_Prim);
pragma Inline (Scope);
pragma Inline (Select_Alternatives);
@@ -11550,6 +11597,7 @@ package Sinfo is
pragma Inline (Set_Has_Task_Info_Pragma);
pragma Inline (Set_Has_Task_Name_Pragma);
pragma Inline (Set_Has_Wide_Character);
+ pragma Inline (Set_Has_Wide_Wide_Character);
pragma Inline (Set_Hidden_By_Use_Clause);
pragma Inline (Set_High_Bound);
pragma Inline (Set_Identifier);
@@ -11664,6 +11712,7 @@ package Sinfo is
pragma Inline (Set_SCIL_Controlling_Tag);
pragma Inline (Set_SCIL_Entity);
pragma Inline (Set_SCIL_Related_Node);
+ pragma Inline (Set_SCIL_Tag_Value);
pragma Inline (Set_SCIL_Target_Prim);
pragma Inline (Set_Scope);
pragma Inline (Set_Select_Alternatives);
diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl
index 9057759cb3f..8195cdbb5e2 100644
--- a/gcc/ada/snames.ads-tmpl
+++ b/gcc/ada/snames.ads-tmpl
@@ -383,6 +383,7 @@ package Snames is
Name_Restrictions : constant Name_Id := N + $;
Name_Restriction_Warnings : constant Name_Id := N + $; -- GNAT
Name_Reviewable : constant Name_Id := N + $;
+ Name_Short_Circuit_And_Or : constant Name_Id := N + $; -- GNAT
Name_Source_File_Name : constant Name_Id := N + $; -- GNAT
Name_Source_File_Name_Project : constant Name_Id := N + $; -- GNAT
Name_Style_Checks : constant Name_Id := N + $; -- GNAT
@@ -1033,10 +1034,12 @@ package Snames is
Name_Compiler : constant Name_Id := N + $;
Name_Compiler_Command : constant Name_Id := N + $; -- GPR
Name_Config_Body_File_Name : constant Name_Id := N + $;
+ Name_Config_Body_File_Name_Index : constant Name_Id := N + $;
Name_Config_Body_File_Name_Pattern : constant Name_Id := N + $;
Name_Config_File_Switches : constant Name_Id := N + $;
Name_Config_File_Unique : constant Name_Id := N + $;
Name_Config_Spec_File_Name : constant Name_Id := N + $;
+ Name_Config_Spec_File_Name_Index : constant Name_Id := N + $;
Name_Config_Spec_File_Name_Pattern : constant Name_Id := N + $;
Name_Configuration : constant Name_Id := N + $;
Name_Cross_Reference : constant Name_Id := N + $;
@@ -1103,6 +1106,8 @@ package Snames is
Name_Mapping_Body_Suffix : constant Name_Id := N + $;
Name_Max_Command_Line_Length : constant Name_Id := N + $;
Name_Metrics : constant Name_Id := N + $;
+ Name_Multi_Unit_Object_Separator : constant Name_Id := N + $;
+ Name_Multi_Unit_Switches : constant Name_Id := N + $;
Name_Naming : constant Name_Id := N + $;
Name_None : constant Name_Id := N + $;
Name_Object_File_Suffix : constant Name_Id := N + $;
@@ -1450,6 +1455,7 @@ package Snames is
Pragma_Restrictions,
Pragma_Restriction_Warnings,
Pragma_Reviewable,
+ Pragma_Short_Circuit_And_Or,
Pragma_Source_File_Name,
Pragma_Source_File_Name_Project,
Pragma_Style_Checks,
diff --git a/gcc/ada/socket.c b/gcc/ada/socket.c
index df3b1206428..76755643161 100644
--- a/gcc/ada/socket.c
+++ b/gcc/ada/socket.c
@@ -35,11 +35,24 @@
#ifdef VMS
/*
* For VMS, gsocket.h can't include sockets-related DEC C header files
- * when building the runtime (because these files are in DEC C archives,
- * not accessable to GCC). So, we generate a separate header file along
- * with s-oscons.ads and include it here.
+ * when building the runtime (because these files are in a DEC C text library
+ * (DECC$RTLDEF.TLB) not accessable to GCC). So, we generate a separate header
+ * file along with s-oscons.ads and include it here.
*/
# include "s-oscons.h"
+
+/*
+ * We also need the declaration of struct servent, which s-oscons can't
+ * provide, so we copy it manually here. This needs to be kept in synch
+ * with the definition of that structure in the DEC C headers, which
+ * hopefully won't change frequently.
+ */
+struct servent {
+ char *s_name; /* official service name */
+ char **s_aliases; /* alias list */
+ int s_port; /* port # */
+ char *s_proto; /* protocol to use */
+};
#endif
#if defined(HAVE_SOCKETS)
@@ -74,6 +87,14 @@ extern void __gnat_remove_socket_from_set (fd_set *, int);
extern void __gnat_reset_socket_set (fd_set *);
extern int __gnat_get_h_errno (void);
extern int __gnat_socket_ioctl (int, int, int *);
+extern char * __gnat_servent_s_name (struct servent *);
+extern char ** __gnat_servent_s_aliases (struct servent *);
+extern int __gnat_servent_s_port (struct servent *);
+extern char * __gnat_servent_s_proto (struct servent *);
+extern void __gnat_servent_set_s_name (struct servent *, char *);
+extern void __gnat_servent_set_s_aliases (struct servent *, char **);
+extern void __gnat_servent_set_s_port (struct servent *, int);
+extern void __gnat_servent_set_s_proto (struct servent *, char *);
#if defined (__vxworks) || defined (_WIN32)
extern int __gnat_inet_pton (int, const char *, void *);
#endif
@@ -488,6 +509,88 @@ __gnat_inet_pton (int af, const char *src, void *dst) {
}
#endif
+/*
+ * Accessor functions for struct servent.
+ *
+ * These are needed because servent has different representations on different
+ * platforms, and we don't want to deal with that on the Ada side. For example,
+ * on Linux, we have (see /usr/include netdb.h):
+ *
+ * struct servent
+ * {
+ * char *s_name;
+ * char **s_aliases;
+ * int s_port;
+ * char *s_proto;
+ * };
+ *
+ * and on Windows (see mingw's socket.h):
+ *
+ * struct servent {
+ * char *s_name;
+ * char **s_aliases;
+ * #ifdef _WIN64
+ * char *s_proto;
+ * short s_port;
+ * #else
+ * short s_port;
+ * char *s_proto;
+ * #endif
+ * };
+ */
+
+/* Getters */
+
+char *
+__gnat_servent_s_name (struct servent * s)
+{
+ return s->s_name;
+}
+
+char **
+__gnat_servent_s_aliases (struct servent * s)
+{
+ return s->s_aliases;
+}
+
+int
+__gnat_servent_s_port (struct servent * s)
+{
+ return s->s_port;
+}
+
+char *
+__gnat_servent_s_proto (struct servent * s)
+{
+ return s->s_proto;
+}
+
+/* Setters */
+
+void
+__gnat_servent_set_s_name (struct servent * s, char * s_name)
+{
+ s->s_name = s_name;
+}
+
+void
+__gnat_servent_set_s_aliases (struct servent * s, char ** s_aliases)
+{
+ s->s_aliases = s_aliases;
+}
+
+void
+__gnat_servent_set_s_port (struct servent * s, int s_port)
+{
+ s->s_port = s_port;
+}
+
+void
+__gnat_servent_set_s_proto (struct servent * s, char * s_proto)
+{
+ s->s_proto = s_proto;
+}
+
#else
# warning Sockets are not supported on this platform
#endif /* defined(HAVE_SOCKETS) */
diff --git a/gcc/ada/sprint.adb b/gcc/ada/sprint.adb
index e73d204d758..cc9d5a081f1 100644
--- a/gcc/ada/sprint.adb
+++ b/gcc/ada/sprint.adb
@@ -35,6 +35,7 @@ with Nlists; use Nlists;
with Opt; use Opt;
with Output; use Output;
with Rtsfind; use Rtsfind;
+with Sem_Eval; use Sem_Eval;
with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
with Sinput; use Sinput;
@@ -526,7 +527,7 @@ package body Sprint is
Write_Eol;
end Underline;
- -- Start of processing for Tree_Dump
+ -- Start of processing for Source_Dump
begin
Dump_Generated_Only := Debug_Flag_G or
@@ -2651,6 +2652,9 @@ package body Sprint is
when N_SCIL_Dispatching_Call =>
Write_Indent_Str ("[N_SCIL_Dispatching_Node]");
+ when N_SCIL_Membership_Test =>
+ Write_Indent_Str ("[N_SCIL_Membership_Test]");
+
when N_SCIL_Tag_Init =>
Write_Indent_Str ("[N_SCIL_Dispatch_Table_Tag_Init]");
@@ -3961,7 +3965,7 @@ package body Sprint is
when E_String_Literal_Subtype =>
declare
LB : constant Uint :=
- Intval (String_Literal_Low_Bound (Typ));
+ Expr_Value (String_Literal_Low_Bound (Typ));
Len : constant Uint :=
String_Literal_Length (Typ);
begin
diff --git a/gcc/ada/switch-m.ads b/gcc/ada/switch-m.ads
index a7301761f93..6a800234083 100644
--- a/gcc/ada/switch-m.ads
+++ b/gcc/ada/switch-m.ads
@@ -43,8 +43,9 @@ package Switch.M is
-- consists of one small letter causes a fatal error exit and control does
-- not return. For all other not recognized switches, Success is set to
-- False, so that the switch may be passed to the compiler.
+ --
-- Project_Node_Tree is used to store tree-specific parameters like the
- -- project path
+ -- project path.
procedure Normalize_Compiler_Switches
(Switch_Chars : String;
diff --git a/gcc/ada/system-vxworks-ppc.ads b/gcc/ada/system-vxworks-ppc.ads
index d355bae9700..38a9def0f6e 100644
--- a/gcc/ada/system-vxworks-ppc.ads
+++ b/gcc/ada/system-vxworks-ppc.ads
@@ -5,7 +5,7 @@
-- S Y S T E M --
-- --
-- S p e c --
--- (VxWorks 5 Version PPC) --
+-- (VxWorks 5 and MILS Version PPC) --
-- --
-- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
-- --
diff --git a/gcc/ada/usage.adb b/gcc/ada/usage.adb
index 541496c5df8..8b0d0cba4e3 100644
--- a/gcc/ada/usage.adb
+++ b/gcc/ada/usage.adb
@@ -38,10 +38,10 @@ procedure Usage is
procedure Write_Switch_Char (Sw : String; Prefix : String := "gnat");
-- Output two spaces followed by the switch character minus followed
- -- Prefix, followed by the string given as the argument, and then
- -- enough blanks to tab to column 13, i.e. assuming Sw is not longer
- -- than 5 characters, the maximum allowed, Write_Switch_Char will
- -- always output exactly 12 characters.
+ -- Prefix, followed by the string given as the argument, and then enough
+ -- blanks to tab to column 13, i.e. assuming Sw is not longer than 5
+ -- characters, the maximum allowed, Write_Switch_Char will always output
+ -- exactly 12 characters.
-----------------------
-- Write_Switch_Char --
@@ -397,9 +397,9 @@ begin
Write_Switch_Char ("wxx");
Write_Line ("Enable selected warning modes, xx = list of parameters:");
- Write_Line (" a turn on all optional warnings " &
+ Write_Line (" a turn on all optional info/warnings " &
"(except dhl.ot.w)");
- Write_Line (" A turn off all optional warnings");
+ Write_Line (" A turn off all optional info/warnings");
Write_Line (" .a* turn on warnings for failing assertion");
Write_Line (" .A turn off warnings for failing assertion");
Write_Line (" b turn on warnings for bad fixed value " &
@@ -414,8 +414,9 @@ begin
Write_Line (" .C* turn off warnings for unrepped components");
Write_Line (" d turn on warnings for implicit dereference");
Write_Line (" D* turn off warnings for implicit dereference");
- Write_Line (" e treat all warnings as errors");
- Write_Line (" .e turn on every optional warning (no exceptions)");
+ Write_Line (" e treat all warnings (but not info) as errors");
+ Write_Line (" .e turn on every optional info/warning " &
+ "(no exceptions)");
Write_Line (" f turn on warnings for unreferenced formal");
Write_Line (" F* turn off warnings for unreferenced formal");
Write_Line (" g* turn on warnings for unrecognized pragma");
@@ -465,18 +466,20 @@ begin
Write_Line (" R* turn off warnings for redundant construct");
Write_Line (" .r turn on warnings for object renaming function");
Write_Line (" .R* turn off warnings for object renaming function");
- Write_Line (" s suppress all warnings");
+ Write_Line (" s suppress all info/warnings");
Write_Line (" t turn on warnings for tracking deleted code");
Write_Line (" T* turn off warnings for tracking deleted code");
Write_Line (" u turn on warnings for unused entity");
Write_Line (" U* turn off warnings for unused entity");
Write_Line (" v* turn on warnings for unassigned variable");
Write_Line (" V turn off warnings for unassigned variable");
+ Write_Line (" .v* turn on info messages for reverse bit order");
+ Write_Line (" .V turn off info messages for reverse bit order");
Write_Line (" w* turn on warnings for wrong low bound assumption");
Write_Line (" W turn off warnings for wrong low bound " &
"assumption");
Write_Line (" .w turn on warnings on pragma Warnings Off");
- Write_Line (" .w* turn off warnings on pragma Warnings Off");
+ Write_Line (" .W* turn off warnings on pragma Warnings Off");
Write_Line (" x* turn on warnings for export/import");
Write_Line (" X turn off warnings for export/import");
Write_Line (" .x turn on warnings for non-local exception");
diff --git a/gcc/ada/vms_data.ads b/gcc/ada/vms_data.ads
index aac1c783c23..6f4ae0f65f0 100644
--- a/gcc/ada/vms_data.ads
+++ b/gcc/ada/vms_data.ads
@@ -1933,6 +1933,13 @@ package VMS_Data is
--
-- Do not look for library files in the system default directory.
+ S_GCC_NoWarnP : aliased constant S := "/NOWARNING_PRAGMAS " &
+ "-gnatd.i";
+ -- /NOWARNING_PRAGMAS
+ --
+ -- Causes all Warnings pragmas to be ignored. Useful to check if the
+ -- program has obsolete warnings pragmas that are hiding problems.
+
S_GCC_Opt : aliased constant S := "/OPTIMIZE=" &
"ALL " &
"-O2,!-O0,!-O1,!-O3 " &
@@ -2976,6 +2983,10 @@ package VMS_Data is
"-gnatwv " &
"NOVARIABLES_UNINITIALIZED " &
"-gnatwV " &
+ "REVERSE_BIT_ORDER " &
+ "-gnatw.v " &
+ "NOREVERSE_BIT_ORDER " &
+ "-gnatw.V " &
"LOWBOUND_ASSUMED " &
"-gnatww " &
"NOLOWBOUND_ASSUMED " &
@@ -3473,6 +3484,7 @@ package VMS_Data is
S_GCC_Noload 'Access,
S_GCC_Nostinc 'Access,
S_GCC_Nostlib 'Access,
+ S_GCC_NoWarnP 'Access,
S_GCC_Opt 'Access,
S_GCC_OptX 'Access,
S_GCC_Pointer 'Access,
diff --git a/gcc/ada/xoscons.adb b/gcc/ada/xoscons.adb
index 83b726b6b9b..afe05efd651 100644
--- a/gcc/ada/xoscons.adb
+++ b/gcc/ada/xoscons.adb
@@ -72,12 +72,15 @@ procedure XOSCons is
end record;
type Asm_Info_Kind is
- (CND, -- Constant (decimal)
- CNS, -- Constant (freeform string)
+ (CND, -- Named number (decimal)
+ CNS, -- Named number (freeform text)
+ C, -- Constant object
TXT); -- Literal text
-- Recognized markers found in assembly file. These markers are produced by
-- the same-named macros from the C template.
+ subtype Named_Number is Asm_Info_Kind range CND .. CNS;
+
type Asm_Info (Kind : Asm_Info_Kind := TXT) is record
Line_Number : Integer;
-- Line number in C source file
@@ -85,11 +88,14 @@ procedure XOSCons is
Constant_Name : String_Access;
-- Name of constant to be defined
+ Constant_Type : String_Access;
+ -- Type of constant (case of Kind = C)
+
Value_Len : Natural := 0;
-- Length of text representation of constant's value
Text_Value : String_Access;
- -- Value for CNS constant
+ -- Value for CNS / C constant
Int_Value : Int_Value_Type;
-- Value for CND constant
@@ -105,8 +111,9 @@ procedure XOSCons is
Table_Initial => 100,
Table_Increment => 10);
- Max_Const_Name_Len : Natural := 0;
+ Max_Constant_Name_Len : Natural := 0;
Max_Constant_Value_Len : Natural := 0;
+ Max_Constant_Type_Len : Natural := 0;
-- Lengths of longest name and longest value
type Language is (Lang_Ada, Lang_C);
@@ -170,13 +177,22 @@ procedure XOSCons is
case Lang is
when Lang_Ada =>
Put (" " & Info.Constant_Name.all);
- Put (Spaces (Max_Const_Name_Len - Info.Constant_Name'Length));
+ Put (Spaces (Max_Constant_Name_Len
+ - Info.Constant_Name'Length));
- Put (" : constant := ");
+ if Info.Kind in Named_Number then
+ Put (" : constant := ");
+ else
+ Put (" : constant " & Info.Constant_Type.all);
+ Put (Spaces (Max_Constant_Type_Len
+ - Info.Constant_Type'Length));
+ Put (" := ");
+ end if;
when Lang_C =>
Put ("#define " & Info.Constant_Name.all & " ");
- Put (Spaces (Max_Const_Name_Len - Info.Constant_Name'Length));
+ Put (Spaces (Max_Constant_Name_Len
+ - Info.Constant_Name'Length));
end case;
if Info.Kind = CND then
@@ -185,7 +201,19 @@ procedure XOSCons is
end if;
Put (Trim (Info.Int_Value.Abs_Value'Img, Side => Left));
else
- Put (Info.Text_Value.all);
+ declare
+ Is_String : constant Boolean :=
+ Info.Kind = C
+ and then Info.Constant_Type.all = "String";
+ begin
+ if Is_String then
+ Put ("""");
+ end if;
+ Put (Info.Text_Value.all);
+ if Is_String then
+ Put ("""");
+ end if;
+ end;
end if;
if Lang = Lang_Ada then
@@ -290,18 +318,28 @@ procedure XOSCons is
Integer (Parse_Int (Line (Index1 .. Index2 - 1)).Abs_Value);
case Info.Kind is
- when CND | CNS =>
+ when CND | CNS | C =>
Index1 := Index2 + 1;
Find_Colon (Index2);
Info.Constant_Name := Field_Alloc;
- if Info.Constant_Name'Length > Max_Const_Name_Len then
- Max_Const_Name_Len := Info.Constant_Name'Length;
+ if Info.Constant_Name'Length > Max_Constant_Name_Len then
+ Max_Constant_Name_Len := Info.Constant_Name'Length;
end if;
Index1 := Index2 + 1;
Find_Colon (Index2);
+ if Info.Kind = C then
+ Info.Constant_Type := Field_Alloc;
+ if Info.Constant_Type'Length > Max_Constant_Type_Len then
+ Max_Constant_Type_Len := Info.Constant_Type'Length;
+ end if;
+
+ Index1 := Index2 + 1;
+ Find_Colon (Index2);
+ end if;
+
if Info.Kind = CND then
Info.Int_Value := Parse_Int (Line (Index1 .. Index2 - 1));
Info.Value_Len := Index2 - Index1 - 1;
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 1017176ff3f..d79d3e4d86b 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -310,6 +310,8 @@ typedef enum {
} cgraph_inline_failed_t;
struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgraph_edge {
+ /* Expected number of executions: calculated in profile.c. */
+ gcov_type count;
struct cgraph_node *caller;
struct cgraph_node *callee;
struct cgraph_edge *prev_caller;
@@ -317,29 +319,27 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgrap
struct cgraph_edge *prev_callee;
struct cgraph_edge *next_callee;
gimple call_stmt;
- /* The stmt_uid of this call stmt. This is used by LTO to recover
- the call_stmt when the function is serialized in. */
- unsigned int lto_stmt_uid;
PTR GTY ((skip (""))) aux;
/* When equal to CIF_OK, inline this call. Otherwise, points to the
explanation why function was not inlined. */
cgraph_inline_failed_t inline_failed;
- /* Expected number of executions: calculated in profile.c. */
- gcov_type count;
+ /* The stmt_uid of call_stmt. This is used by LTO to recover the call_stmt
+ when the function is serialized in. */
+ unsigned int lto_stmt_uid;
/* Expected frequency of executions within the function.
When set to CGRAPH_FREQ_BASE, the edge is expected to be called once
per function call. The range is 0 to CGRAPH_FREQ_MAX. */
int frequency;
+ /* Unique id of the edge. */
+ int uid;
/* Depth of loop nest, 1 means no loop nest. */
- unsigned int loop_nest : 30;
+ unsigned short int loop_nest;
/* Whether this edge describes a call that was originally indirect. */
unsigned int indirect_call : 1;
/* True if the corresponding CALL stmt cannot be inlined. */
unsigned int call_stmt_cannot_inline_p : 1;
/* Can this call throw externally? */
unsigned int can_throw_external : 1;
- /* Unique id of the edge. */
- int uid;
};
#define CGRAPH_FREQ_BASE 1000
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index e3825433d87..51ead06bc4a 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -135,6 +135,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-dump.h"
#include "output.h"
#include "coverage.h"
+#include "plugin.h"
static void cgraph_expand_all_functions (void);
static void cgraph_mark_functions_to_output (void);
@@ -1712,6 +1713,8 @@ ipa_passes (void)
gimple_register_cfg_hooks ();
bitmap_obstack_initialize (NULL);
+ invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL);
+
if (!in_lto_p)
execute_ipa_pass_list (all_small_ipa_passes);
@@ -1730,7 +1733,8 @@ ipa_passes (void)
current_function_decl = NULL;
cgraph_process_new_functions ();
- execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
+ execute_ipa_summary_passes
+ ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
}
execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
@@ -1739,6 +1743,7 @@ ipa_passes (void)
if (!flag_ltrans)
execute_ipa_pass_list (all_regular_ipa_passes);
+ invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
bitmap_obstack_release (NULL);
}
diff --git a/gcc/config.in b/gcc/config.in
index fbc9fbb9288..681e4f8bd48 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -1634,6 +1634,13 @@
#endif
+/* Define if you want to generate code by default that assumes that the Cygwin
+ DLL exports wrappers to support libstdc++ function replacement. */
+#ifndef USED_FOR_TARGET
+#undef USE_CYGWIN_LIBSTDCXX_WRAPPERS
+#endif
+
+
/* Define to 1 if the 'long long' (or '__int64') is wider than 'long' but
still efficiently supported by the host hardware. */
#ifndef USED_FOR_TARGET
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 3f349547a92..691a8600e0a 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1275,7 +1275,7 @@ enum reg_class
In general this is just CLASS, but for the Thumb core registers and
immediate constants we prefer a LO_REGS class or a subset. */
#define PREFERRED_RELOAD_CLASS(X, CLASS) \
- (TARGET_ARM ? (CLASS) : \
+ (TARGET_32BIT ? (CLASS) : \
((CLASS) == GENERAL_REGS || (CLASS) == HI_REGS \
|| (CLASS) == NO_REGS || (CLASS) == STACK_REG \
? LO_REGS : (CLASS)))
diff --git a/gcc/config/i386/abmintrin.h b/gcc/config/i386/abmintrin.h
new file mode 100644
index 00000000000..b85bdb77348
--- /dev/null
+++ b/gcc/config/i386/abmintrin.h
@@ -0,0 +1,70 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+
+ 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.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _X86INTRIN_H_INCLUDED
+# error "Never use <abmintrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef __ABM__
+# error "ABM instruction set not enabled"
+#endif /* __ABM__ */
+
+#ifndef _ABMINTRIN_H_INCLUDED
+#define _ABMINTRIN_H_INCLUDED
+
+extern __inline unsigned short __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__lzcnt16 (unsigned short __X)
+{
+ return __builtin_clzs (__X);
+}
+
+extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__lzcnt (unsigned int __X)
+{
+ return __builtin_clz (__X);
+}
+
+#ifdef __x86_64__
+extern __inline unsigned long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__lzcnt64 (unsigned long __X)
+{
+ return __builtin_clzl (__X);
+}
+#endif
+
+/* Calculate a number of bits set to 1. */
+extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_popcnt_u32 (unsigned int __X)
+{
+ return __builtin_popcount (__X);
+}
+
+#ifdef __x86_64__
+extern __inline long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_popcnt_u64 (unsigned long long __X)
+{
+ return __builtin_popcountll (__X);
+}
+#endif
+
+#endif /* _ABMINTRIN_H_INCLUDED */
diff --git a/gcc/config/i386/cygming.opt b/gcc/config/i386/cygming.opt
index e845a0d5827..72dfc3401bb 100644
--- a/gcc/config/i386/cygming.opt
+++ b/gcc/config/i386/cygming.opt
@@ -1,6 +1,6 @@
; Cygwin- and MinGW-specific options.
-; Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+; Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
;
; This file is part of GCC.
;
@@ -49,3 +49,7 @@ Create GUI application
mpe-aligned-commons
Target Var(use_pe_aligned_common) Init(HAVE_GAS_ALIGNED_COMM)
Use the GNU extension to the PE format for aligned common data
+
+muse-libstdc-wrappers
+Target Condition({defined (USE_CYGWIN_LIBSTDCXX_WRAPPERS)})
+Compile code that relies on Cygwin DLL wrappers to support C++ operator new/delete replacement
diff --git a/gcc/config/i386/cygwin.h b/gcc/config/i386/cygwin.h
index 8eb21da4948..86eff635ae6 100644
--- a/gcc/config/i386/cygwin.h
+++ b/gcc/config/i386/cygwin.h
@@ -85,9 +85,41 @@ along with GCC; see the file COPYING3. If not see
%{mwindows:-lgdi32 -lcomdlg32} \
-luser32 -lkernel32 -ladvapi32 -lshell32"
+/* To implement C++ function replacement we always wrap the cxx
+ malloc-like operators. See N2800 #17.6.4.6 [replacement.functions] */
+#define CXX_WRAP_SPEC_LIST "%{!static: %{!static-libstdc++: \
+ --wrap _Znwj \
+ --wrap _Znaj \
+ --wrap _ZdlPv \
+ --wrap _ZdaPv \
+ --wrap _ZnwjRKSt9nothrow_t \
+ --wrap _ZnajRKSt9nothrow_t \
+ --wrap _ZdlPvRKSt9nothrow_t \
+ --wrap _ZdaPvRKSt9nothrow_t \
+ }}"
+
+#if defined (USE_CYGWIN_LIBSTDCXX_WRAPPERS)
+
+#if USE_CYGWIN_LIBSTDCXX_WRAPPERS
+/* Default on, only explict -mno disables. */
+#define CXX_WRAP_SPEC_OPT "!mno-use-libstdc-wrappers"
+#else
+/* Default off, only explict -m enables. */
+#define CXX_WRAP_SPEC_OPT "muse-libstdc-wrappers"
+#endif
+
+#define CXX_WRAP_SPEC "%{" CXX_WRAP_SPEC_OPT ":" CXX_WRAP_SPEC_LIST "}"
+
+#else /* !defined (USE_CYGWIN_LIBSTDCXX_WRAPPERS) */
+
+#define CXX_WRAP_SPEC ""
+
+#endif /* ?defined (USE_CYGWIN_LIBSTDCXX_WRAPPERS) */
+
#define LINK_SPEC "\
%{mwindows:--subsystem windows} \
%{mconsole:--subsystem console} \
+ " CXX_WRAP_SPEC " \
%{shared: %{mdll: %eshared and mdll are not compatible}} \
%{shared: --shared} %{mdll:--dll} \
%{static:-Bstatic} %{!static:-Bdynamic} \
diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def
index 9f45a13cc31..e9e4d0c4c83 100644
--- a/gcc/config/i386/i386-builtin-types.def
+++ b/gcc/config/i386/i386-builtin-types.def
@@ -142,6 +142,7 @@ DEF_FUNCTION_TYPE (INT64, INT64)
DEF_FUNCTION_TYPE (INT64, V2DF)
DEF_FUNCTION_TYPE (INT64, V4SF)
DEF_FUNCTION_TYPE (UINT64, INT)
+DEF_FUNCTION_TYPE (UINT16, UINT16)
DEF_FUNCTION_TYPE (UINT64, PUNSIGNED)
DEF_FUNCTION_TYPE (V16QI, PCCHAR)
DEF_FUNCTION_TYPE (V16QI, V16QI)
@@ -351,6 +352,8 @@ DEF_FUNCTION_TYPE (V2UDI, V2UDI, V2UDI, V2UDI)
DEF_FUNCTION_TYPE (V4USI, V4USI, V4USI, V4USI)
DEF_FUNCTION_TYPE (V8UHI, V8UHI, V8UHI, V8UHI)
DEF_FUNCTION_TYPE (V16UQI, V16UQI, V16UQI, V16UQI)
+DEF_FUNCTION_TYPE (V4DF, V4DF, V4DF, V4DI)
+DEF_FUNCTION_TYPE (V8SF, V8SF, V8SF, V8SI)
DEF_FUNCTION_TYPE (V2DI, V2DI, V2DI, UINT, UINT)
DEF_FUNCTION_TYPE (V4HI, HI, HI, HI, HI)
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index 5a5311fba0f..cba9ceb19ae 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -236,6 +236,8 @@ ix86_target_macros_internal (int isa_flag,
def_or_undef (parse_in, "__XOP__");
if (isa_flag & OPTION_MASK_ISA_LWP)
def_or_undef (parse_in, "__LWP__");
+ if (isa_flag & OPTION_MASK_ISA_ABM)
+ def_or_undef (parse_in, "__ABM__");
if ((fpmath & FPMATH_SSE) && (isa_flag & OPTION_MASK_ISA_SSE))
def_or_undef (parse_in, "__SSE_MATH__");
if ((fpmath & FPMATH_SSE) && (isa_flag & OPTION_MASK_ISA_SSE2))
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 88acc1f82a6..1451e799fa6 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -48,6 +48,7 @@ extern bool x86_extended_reg_mentioned_p (rtx);
extern enum machine_mode ix86_cc_mode (enum rtx_code, rtx, rtx);
extern int avx_vpermilp_parallel (rtx par, enum machine_mode mode);
+extern int avx_vperm2f128_parallel (rtx par, enum machine_mode mode);
extern int ix86_expand_movmem (rtx, rtx, rtx, rtx, rtx, rtx);
extern int ix86_expand_setmem (rtx, rtx, rtx, rtx, rtx, rtx);
@@ -85,6 +86,7 @@ extern void ix86_expand_binary_operator (enum rtx_code,
enum machine_mode, rtx[]);
extern int ix86_binary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
extern bool ix86_lea_for_add_ok (enum rtx_code, rtx, rtx[]);
+extern bool ix86_vec_interleave_v2df_operator_ok (rtx operands[3], bool high);
extern bool ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn);
extern bool ix86_agi_dependent (rtx set_insn, rtx use_insn);
extern void ix86_expand_unary_operator (enum rtx_code, enum machine_mode,
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 37fe24f6798..462f2d55648 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -13849,6 +13849,19 @@ ix86_unary_operator_ok (enum rtx_code code ATTRIBUTE_UNUSED,
return TRUE;
}
+/* Return TRUE if the operands to a vec_interleave_{high,low}v2df
+ are ok, keeping in mind the possible movddup alternative. */
+
+bool
+ix86_vec_interleave_v2df_operator_ok (rtx operands[3], bool high)
+{
+ if (MEM_P (operands[0]))
+ return rtx_equal_p (operands[0], operands[1 + high]);
+ if (MEM_P (operands[1]) && MEM_P (operands[2]))
+ return TARGET_SSE3 && rtx_equal_p (operands[1], operands[2]);
+ return true;
+}
+
/* Post-reload splitter for converting an SF or DFmode value in an
SSE register into an unsigned SImode. */
@@ -21047,6 +21060,8 @@ enum ix86_builtins
IX86_BUILTIN_VEC_PERM_V4SI_U,
IX86_BUILTIN_VEC_PERM_V8HI_U,
IX86_BUILTIN_VEC_PERM_V16QI_U,
+ IX86_BUILTIN_VEC_PERM_V4DF,
+ IX86_BUILTIN_VEC_PERM_V8SF,
/* FMA4 and XOP instructions. */
IX86_BUILTIN_VFMADDSS,
@@ -21239,6 +21254,8 @@ enum ix86_builtins
IX86_BUILTIN_LWPINS32,
IX86_BUILTIN_LWPINS64,
+ IX86_BUILTIN_CLZS,
+
IX86_BUILTIN_MAX
};
@@ -21478,11 +21495,11 @@ static const struct builtin_description bdesc_special_args[] =
{ OPTION_MASK_ISA_AVX, CODE_FOR_avx_vzeroall, "__builtin_ia32_vzeroall", IX86_BUILTIN_VZEROALL, UNKNOWN, (int) VOID_FTYPE_VOID },
{ OPTION_MASK_ISA_AVX, CODE_FOR_avx_vzeroupper, "__builtin_ia32_vzeroupper", IX86_BUILTIN_VZEROUPPER, UNKNOWN, (int) VOID_FTYPE_VOID },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vbroadcastss, "__builtin_ia32_vbroadcastss", IX86_BUILTIN_VBROADCASTSS, UNKNOWN, (int) V4SF_FTYPE_PCFLOAT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vbroadcastsd256, "__builtin_ia32_vbroadcastsd256", IX86_BUILTIN_VBROADCASTSD256, UNKNOWN, (int) V4DF_FTYPE_PCDOUBLE },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vbroadcastss256, "__builtin_ia32_vbroadcastss256", IX86_BUILTIN_VBROADCASTSS256, UNKNOWN, (int) V8SF_FTYPE_PCFLOAT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vbroadcastf128_pd256, "__builtin_ia32_vbroadcastf128_pd256", IX86_BUILTIN_VBROADCASTPD256, UNKNOWN, (int) V4DF_FTYPE_PCV2DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vbroadcastf128_ps256, "__builtin_ia32_vbroadcastf128_ps256", IX86_BUILTIN_VBROADCASTPS256, UNKNOWN, (int) V8SF_FTYPE_PCV4SF },
+ { OPTION_MASK_ISA_AVX, CODE_FOR_vec_dupv4sf, "__builtin_ia32_vbroadcastss", IX86_BUILTIN_VBROADCASTSS, UNKNOWN, (int) V4SF_FTYPE_PCFLOAT },
+ { OPTION_MASK_ISA_AVX, CODE_FOR_vec_dupv4df, "__builtin_ia32_vbroadcastsd256", IX86_BUILTIN_VBROADCASTSD256, UNKNOWN, (int) V4DF_FTYPE_PCDOUBLE },
+ { OPTION_MASK_ISA_AVX, CODE_FOR_vec_dupv8sf, "__builtin_ia32_vbroadcastss256", IX86_BUILTIN_VBROADCASTSS256, UNKNOWN, (int) V8SF_FTYPE_PCFLOAT },
+ { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vbroadcastf128_v4df, "__builtin_ia32_vbroadcastf128_pd256", IX86_BUILTIN_VBROADCASTPD256, UNKNOWN, (int) V4DF_FTYPE_PCV2DF },
+ { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vbroadcastf128_v8sf, "__builtin_ia32_vbroadcastf128_ps256", IX86_BUILTIN_VBROADCASTPS256, UNKNOWN, (int) V8SF_FTYPE_PCV4SF },
{ OPTION_MASK_ISA_AVX, CODE_FOR_avx_movupd256, "__builtin_ia32_loadupd256", IX86_BUILTIN_LOADUPD256, UNKNOWN, (int) V4DF_FTYPE_PCDOUBLE },
{ OPTION_MASK_ISA_AVX, CODE_FOR_avx_movups256, "__builtin_ia32_loadups256", IX86_BUILTIN_LOADUPS256, UNKNOWN, (int) V8SF_FTYPE_PCFLOAT },
@@ -21520,6 +21537,8 @@ static const struct builtin_description bdesc_special_args[] =
{ OPTION_MASK_ISA_LWP, CODE_FOR_lwp_lwpinssi3, "__builtin_ia32_lwpins32", IX86_BUILTIN_LWPINS64, UNKNOWN, (int) UCHAR_FTYPE_UINT_UINT_UINT },
{ OPTION_MASK_ISA_LWP, CODE_FOR_lwp_lwpinsdi3, "__builtin_ia32_lwpins64", IX86_BUILTIN_LWPINS64, UNKNOWN, (int) UCHAR_FTYPE_UINT64_UINT_UINT },
+ { OPTION_MASK_ISA_ABM, CODE_FOR_clzhi2_abm, "__builtin_clzs", IX86_BUILTIN_CLZS, UNKNOWN, (int) UINT16_FTYPE_UINT16 },
+
};
/* Builtins with variable number of arguments. */
@@ -21722,7 +21741,7 @@ static const struct builtin_description bdesc_args[] =
{ OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_shufpd, "__builtin_ia32_shufpd", IX86_BUILTIN_SHUFPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_INT },
{ OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v2df", IX86_BUILTIN_VEC_PERM_V2DF, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_V2DI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v4sf", IX86_BUILTIN_VEC_PERM_V4SF, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_V4SI },
+ { OPTION_MASK_ISA_SSE, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v4sf", IX86_BUILTIN_VEC_PERM_V4SF, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_V4SI },
{ OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v2di", IX86_BUILTIN_VEC_PERM_V2DI, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_V2DI },
{ OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v4si", IX86_BUILTIN_VEC_PERM_V4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI },
{ OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v8hi", IX86_BUILTIN_VEC_PERM_V8HI, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI },
@@ -21731,6 +21750,8 @@ static const struct builtin_description bdesc_args[] =
{ OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v4si_u", IX86_BUILTIN_VEC_PERM_V4SI_U, UNKNOWN, (int) V4USI_FTYPE_V4USI_V4USI_V4USI },
{ OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v8hi_u", IX86_BUILTIN_VEC_PERM_V8HI_U, UNKNOWN, (int) V8UHI_FTYPE_V8UHI_V8UHI_V8UHI },
{ OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v16qi_u", IX86_BUILTIN_VEC_PERM_V16QI_U, UNKNOWN, (int) V16UQI_FTYPE_V16UQI_V16UQI_V16UQI },
+ { OPTION_MASK_ISA_AVX, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v4df", IX86_BUILTIN_VEC_PERM_V4DF, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF_V4DI },
+ { OPTION_MASK_ISA_AVX, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v8sf", IX86_BUILTIN_VEC_PERM_V8SF, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF_V8SI },
{ OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_movmskpd, "__builtin_ia32_movmskpd", IX86_BUILTIN_MOVMSKPD, UNKNOWN, (int) INT_FTYPE_V2DF },
{ OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_pmovmskb, "__builtin_ia32_pmovmskb128", IX86_BUILTIN_PMOVMSKB128, UNKNOWN, (int) INT_FTYPE_V16QI },
@@ -23342,6 +23363,7 @@ ix86_expand_args_builtin (const struct builtin_description *d,
case FLOAT_FTYPE_FLOAT:
case INT_FTYPE_INT:
case UINT64_FTYPE_INT:
+ case UINT16_FTYPE_UINT16:
case INT64_FTYPE_INT64:
case INT64_FTYPE_V4SF:
case INT64_FTYPE_V2DF:
@@ -24151,6 +24173,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
case IX86_BUILTIN_VEC_PERM_V4SI_U:
case IX86_BUILTIN_VEC_PERM_V8HI_U:
case IX86_BUILTIN_VEC_PERM_V16QI_U:
+ case IX86_BUILTIN_VEC_PERM_V4DF:
+ case IX86_BUILTIN_VEC_PERM_V8SF:
return ix86_expand_vec_perm_builtin (exp);
case IX86_BUILTIN_INFQ:
@@ -24591,7 +24615,7 @@ avx_vpermilp_parallel (rtx par, enum machine_mode mode)
if (!CONST_INT_P (er))
return 0;
ei = INTVAL (er);
- if (ei >= nelt)
+ if (ei >= 2 * nelt)
return 0;
ipar[i] = ei;
}
@@ -24640,6 +24664,58 @@ avx_vpermilp_parallel (rtx par, enum machine_mode mode)
/* Make sure success has a non-zero value by adding one. */
return mask + 1;
}
+
+/* Helper for avx_vperm2f128_v4df_operand et al. This is also used by
+ the expansion functions to turn the parallel back into a mask.
+ The return value is 0 for no match and the imm8+1 for a match. */
+
+int
+avx_vperm2f128_parallel (rtx par, enum machine_mode mode)
+{
+ unsigned i, nelt = GET_MODE_NUNITS (mode), nelt2 = nelt / 2;
+ unsigned mask = 0;
+ unsigned char ipar[8];
+
+ if (XVECLEN (par, 0) != (int) nelt)
+ return 0;
+
+ /* Validate that all of the elements are constants, and not totally
+ out of range. Copy the data into an integral array to make the
+ subsequent checks easier. */
+ for (i = 0; i < nelt; ++i)
+ {
+ rtx er = XVECEXP (par, 0, i);
+ unsigned HOST_WIDE_INT ei;
+
+ if (!CONST_INT_P (er))
+ return 0;
+ ei = INTVAL (er);
+ if (ei >= 2 * nelt)
+ return 0;
+ ipar[i] = ei;
+ }
+
+ /* Validate that the halves of the permute are halves. */
+ for (i = 0; i < nelt2 - 1; ++i)
+ if (ipar[i] + 1 != ipar[i + 1])
+ return 0;
+ for (i = nelt2; i < nelt - 1; ++i)
+ if (ipar[i] + 1 != ipar[i + 1])
+ return 0;
+
+ /* Reconstruct the mask. */
+ for (i = 0; i < 2; ++i)
+ {
+ unsigned e = ipar[i * nelt2];
+ if (e % nelt2)
+ return 0;
+ e /= nelt2;
+ mask |= e << (i * 4);
+ }
+
+ /* Make sure success has a non-zero value by adding one. */
+ return mask + 1;
+}
/* Store OPERAND to the memory after reload is completed. This means
@@ -25655,6 +25731,16 @@ ix86_rtx_costs (rtx x, int code, int outer_code_i, int *total, bool speed)
*total = 0;
return false;
+ case VEC_SELECT:
+ case VEC_CONCAT:
+ case VEC_MERGE:
+ case VEC_DUPLICATE:
+ /* ??? Assume all of these vector manipulation patterns are
+ recognizable. In which case they all pretty much have the
+ same cost. */
+ *total = COSTS_N_INSNS (1);
+ return true;
+
default:
return false;
}
@@ -26489,16 +26575,43 @@ x86_emit_floatuns (rtx operands[2])
emit_label (donelab);
}
+/* AVX does not support 32-byte integer vector operations,
+ thus the longest vector we are faced with is V16QImode. */
+#define MAX_VECT_LEN 16
+
+struct expand_vec_perm_d
+{
+ rtx target, op0, op1;
+ unsigned char perm[MAX_VECT_LEN];
+ enum machine_mode vmode;
+ unsigned char nelt;
+ bool testing_p;
+};
+
+static bool expand_vec_perm_1 (struct expand_vec_perm_d *d);
+static bool expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d);
+
+/* Get a vector mode of the same size as the original but with elements
+ twice as wide. This is only guaranteed to apply to integral vectors. */
+
+static inline enum machine_mode
+get_mode_wider_vector (enum machine_mode o)
+{
+ /* ??? Rely on the ordering that genmodes.c gives to vectors. */
+ enum machine_mode n = GET_MODE_WIDER_MODE (o);
+ gcc_assert (GET_MODE_NUNITS (o) == GET_MODE_NUNITS (n) * 2);
+ gcc_assert (GET_MODE_SIZE (o) == GET_MODE_SIZE (n));
+ return n;
+}
+
/* A subroutine of ix86_expand_vector_init. Store into TARGET a vector
with all elements equal to VAR. Return true if successful. */
-/* ??? Call into the vec_perm support to implement the broadcast. */
static bool
ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
rtx target, rtx val)
{
- enum machine_mode hmode, smode, wsmode, wvmode;
- rtx x;
+ bool ok;
switch (mode)
{
@@ -26508,13 +26621,28 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
return false;
/* FALLTHRU */
+ case V4DFmode:
+ case V4DImode:
+ case V8SFmode:
+ case V8SImode:
case V2DFmode:
case V2DImode:
case V4SFmode:
case V4SImode:
- val = force_reg (GET_MODE_INNER (mode), val);
- x = gen_rtx_VEC_DUPLICATE (mode, val);
- emit_insn (gen_rtx_SET (VOIDmode, target, x));
+ {
+ rtx insn, dup;
+
+ /* First attempt to recognize VAL as-is. */
+ dup = gen_rtx_VEC_DUPLICATE (mode, val);
+ insn = emit_insn (gen_rtx_SET (VOIDmode, target, dup));
+ if (recog_memoized (insn) < 0)
+ {
+ /* If that fails, force VAL into a register. */
+ XEXP (dup, 0) = force_reg (GET_MODE_INNER (mode), val);
+ ok = recog_memoized (insn) >= 0;
+ gcc_assert (ok);
+ }
+ }
return true;
case V4HImode:
@@ -26522,130 +26650,87 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
return false;
if (TARGET_SSE || TARGET_3DNOW_A)
{
+ rtx x;
+
val = gen_lowpart (SImode, val);
x = gen_rtx_TRUNCATE (HImode, val);
x = gen_rtx_VEC_DUPLICATE (mode, x);
emit_insn (gen_rtx_SET (VOIDmode, target, x));
return true;
}
- else
- {
- smode = HImode;
- wsmode = SImode;
- wvmode = V2SImode;
- goto widen;
- }
+ goto widen;
case V8QImode:
if (!mmx_ok)
return false;
- smode = QImode;
- wsmode = HImode;
- wvmode = V4HImode;
goto widen;
+
case V8HImode:
if (TARGET_SSE2)
{
+ struct expand_vec_perm_d dperm;
rtx tmp1, tmp2;
- /* Extend HImode to SImode using a paradoxical SUBREG. */
+
+ permute:
+ memset (&dperm, 0, sizeof (dperm));
+ dperm.target = target;
+ dperm.vmode = mode;
+ dperm.nelt = GET_MODE_NUNITS (mode);
+ dperm.op0 = dperm.op1 = gen_reg_rtx (mode);
+
+ /* Extend to SImode using a paradoxical SUBREG. */
tmp1 = gen_reg_rtx (SImode);
emit_move_insn (tmp1, gen_lowpart (SImode, val));
- /* Insert the SImode value as low element of V4SImode vector. */
- tmp2 = gen_reg_rtx (V4SImode);
- tmp1 = gen_rtx_VEC_MERGE (V4SImode,
- gen_rtx_VEC_DUPLICATE (V4SImode, tmp1),
- CONST0_RTX (V4SImode),
- const1_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, tmp2, tmp1));
- /* Cast the V4SImode vector back to a V8HImode vector. */
- tmp1 = gen_reg_rtx (V8HImode);
- emit_move_insn (tmp1, gen_lowpart (V8HImode, tmp2));
- /* Duplicate the low short through the whole low SImode word. */
- emit_insn (gen_vec_interleave_lowv8hi (tmp1, tmp1, tmp1));
- /* Cast the V8HImode vector back to a V4SImode vector. */
- tmp2 = gen_reg_rtx (V4SImode);
- emit_move_insn (tmp2, gen_lowpart (V4SImode, tmp1));
- /* Replicate the low element of the V4SImode vector. */
- emit_insn (gen_sse2_pshufd (tmp2, tmp2, const0_rtx));
- /* Cast the V2SImode back to V8HImode, and store in target. */
- emit_move_insn (target, gen_lowpart (V8HImode, tmp2));
- return true;
+
+ /* Insert the SImode value as low element of a V4SImode vector. */
+ tmp2 = gen_lowpart (V4SImode, dperm.op0);
+ emit_insn (gen_vec_setv4si_0 (tmp2, CONST0_RTX (V4SImode), tmp1));
+
+ ok = (expand_vec_perm_1 (&dperm)
+ || expand_vec_perm_broadcast_1 (&dperm));
+ gcc_assert (ok);
+ return ok;
}
- smode = HImode;
- wsmode = SImode;
- wvmode = V4SImode;
goto widen;
+
case V16QImode:
if (TARGET_SSE2)
- {
- rtx tmp1, tmp2;
- /* Extend QImode to SImode using a paradoxical SUBREG. */
- tmp1 = gen_reg_rtx (SImode);
- emit_move_insn (tmp1, gen_lowpart (SImode, val));
- /* Insert the SImode value as low element of V4SImode vector. */
- tmp2 = gen_reg_rtx (V4SImode);
- tmp1 = gen_rtx_VEC_MERGE (V4SImode,
- gen_rtx_VEC_DUPLICATE (V4SImode, tmp1),
- CONST0_RTX (V4SImode),
- const1_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, tmp2, tmp1));
- /* Cast the V4SImode vector back to a V16QImode vector. */
- tmp1 = gen_reg_rtx (V16QImode);
- emit_move_insn (tmp1, gen_lowpart (V16QImode, tmp2));
- /* Duplicate the low byte through the whole low SImode word. */
- emit_insn (gen_vec_interleave_lowv16qi (tmp1, tmp1, tmp1));
- emit_insn (gen_vec_interleave_lowv16qi (tmp1, tmp1, tmp1));
- /* Cast the V16QImode vector back to a V4SImode vector. */
- tmp2 = gen_reg_rtx (V4SImode);
- emit_move_insn (tmp2, gen_lowpart (V4SImode, tmp1));
- /* Replicate the low element of the V4SImode vector. */
- emit_insn (gen_sse2_pshufd (tmp2, tmp2, const0_rtx));
- /* Cast the V2SImode back to V16QImode, and store in target. */
- emit_move_insn (target, gen_lowpart (V16QImode, tmp2));
- return true;
- }
- smode = QImode;
- wsmode = HImode;
- wvmode = V8HImode;
+ goto permute;
goto widen;
+
widen:
/* Replicate the value once into the next wider mode and recurse. */
- val = convert_modes (wsmode, smode, val, true);
- x = expand_simple_binop (wsmode, ASHIFT, val,
- GEN_INT (GET_MODE_BITSIZE (smode)),
- NULL_RTX, 1, OPTAB_LIB_WIDEN);
- val = expand_simple_binop (wsmode, IOR, val, x, x, 1, OPTAB_LIB_WIDEN);
-
- x = gen_reg_rtx (wvmode);
- if (!ix86_expand_vector_init_duplicate (mmx_ok, wvmode, x, val))
- gcc_unreachable ();
- emit_move_insn (target, gen_lowpart (mode, x));
- return true;
+ {
+ enum machine_mode smode, wsmode, wvmode;
+ rtx x;
+
+ smode = GET_MODE_INNER (mode);
+ wvmode = get_mode_wider_vector (mode);
+ wsmode = GET_MODE_INNER (wvmode);
+
+ val = convert_modes (wsmode, smode, val, true);
+ x = expand_simple_binop (wsmode, ASHIFT, val,
+ GEN_INT (GET_MODE_BITSIZE (smode)),
+ NULL_RTX, 1, OPTAB_LIB_WIDEN);
+ val = expand_simple_binop (wsmode, IOR, val, x, x, 1, OPTAB_LIB_WIDEN);
+
+ x = gen_lowpart (wvmode, target);
+ ok = ix86_expand_vector_init_duplicate (mmx_ok, wvmode, x, val);
+ gcc_assert (ok);
+ return ok;
+ }
- case V4DFmode:
- hmode = V2DFmode;
- goto half;
- case V4DImode:
- hmode = V2DImode;
- goto half;
- case V8SFmode:
- hmode = V4SFmode;
- goto half;
- case V8SImode:
- hmode = V4SImode;
- goto half;
case V16HImode:
- hmode = V8HImode;
- goto half;
case V32QImode:
- hmode = V16QImode;
- goto half;
-half:
{
- rtx tmp = gen_reg_rtx (hmode);
- ix86_expand_vector_init_duplicate (mmx_ok, hmode, tmp, val);
- emit_insn (gen_rtx_SET (VOIDmode, target,
- gen_rtx_VEC_CONCAT (mode, tmp, tmp)));
+ enum machine_mode hvmode = (mode == V16HImode ? V8HImode : V16QImode);
+ rtx x = gen_reg_rtx (hvmode);
+
+ ok = ix86_expand_vector_init_duplicate (false, hvmode, x, val);
+ gcc_assert (ok);
+
+ x = gen_rtx_VEC_CONCAT (mode, x, x);
+ emit_insn (gen_rtx_SET (VOIDmode, target, x));
}
return true;
@@ -28976,21 +29061,33 @@ ix86_vectorize_builtin_vec_perm (tree vec_type, tree *mask_type)
{
tree itype = TREE_TYPE (vec_type);
bool u = TYPE_UNSIGNED (itype);
+ enum machine_mode vmode = TYPE_MODE (vec_type);
enum ix86_builtins fcode;
+ bool ok = TARGET_SSE2;
- if (!TARGET_SSE2)
- return NULL_TREE;
-
- switch (TYPE_MODE (vec_type))
+ switch (vmode)
{
+ case V4DFmode:
+ ok = TARGET_AVX;
+ fcode = IX86_BUILTIN_VEC_PERM_V4DF;
+ goto get_di;
case V2DFmode:
- itype = ix86_get_builtin_type (IX86_BT_DI);
fcode = IX86_BUILTIN_VEC_PERM_V2DF;
+ get_di:
+ itype = ix86_get_builtin_type (IX86_BT_DI);
break;
+
+ case V8SFmode:
+ ok = TARGET_AVX;
+ fcode = IX86_BUILTIN_VEC_PERM_V8SF;
+ goto get_si;
case V4SFmode:
- itype = ix86_get_builtin_type (IX86_BT_SI);
+ ok = TARGET_SSE;
fcode = IX86_BUILTIN_VEC_PERM_V4SF;
+ get_si:
+ itype = ix86_get_builtin_type (IX86_BT_SI);
break;
+
case V2DImode:
fcode = u ? IX86_BUILTIN_VEC_PERM_V2DI_U : IX86_BUILTIN_VEC_PERM_V2DI;
break;
@@ -29004,26 +29101,17 @@ ix86_vectorize_builtin_vec_perm (tree vec_type, tree *mask_type)
fcode = u ? IX86_BUILTIN_VEC_PERM_V16QI_U : IX86_BUILTIN_VEC_PERM_V16QI;
break;
default:
- return NULL_TREE;
+ ok = false;
+ break;
}
+ if (!ok)
+ return NULL_TREE;
+
*mask_type = itype;
return ix86_builtins[(int) fcode];
}
-/* AVX does not support 32-byte integer vector operations,
- thus the longest vector we are faced with is V16QImode. */
-#define MAX_VECT_LEN 16
-
-struct expand_vec_perm_d
-{
- rtx target, op0, op1;
- unsigned char perm[MAX_VECT_LEN];
- enum machine_mode vmode;
- unsigned char nelt;
- bool testing_p;
-};
-
/* Return a vector mode with twice as many elements as VMODE. */
/* ??? Consider moving this to a table generated by genmodes.c. */
@@ -29619,8 +29707,9 @@ expand_vec_perm_pshufb2 (struct expand_vec_perm_d *d)
rtx rperm[2][16], vperm, l, h, op, m128;
unsigned int i, nelt, eltsz;
- if (!TARGET_SSSE3)
+ if (!TARGET_SSSE3 || GET_MODE_SIZE (d->vmode) != 16)
return false;
+ gcc_assert (d->op0 != d->op1);
nelt = d->nelt;
eltsz = GET_MODE_SIZE (GET_MODE_INNER (d->vmode));
@@ -29664,8 +29753,8 @@ expand_vec_perm_pshufb2 (struct expand_vec_perm_d *d)
return true;
}
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Pattern match
- extract-even and extract-odd permutations. */
+/* A subroutine of ix86_expand_vec_perm_builtin_1. Implement extract-even
+ and extract-odd permutations. */
static bool
expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd)
@@ -29780,6 +29869,9 @@ expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd)
return true;
}
+/* A subroutine of ix86_expand_vec_perm_builtin_1. Pattern match
+ extract-even and extract-odd permutations. */
+
static bool
expand_vec_perm_even_odd (struct expand_vec_perm_d *d)
{
@@ -29796,6 +29888,84 @@ expand_vec_perm_even_odd (struct expand_vec_perm_d *d)
return expand_vec_perm_even_odd_1 (d, odd);
}
+/* A subroutine of ix86_expand_vec_perm_builtin_1. Implement broadcast
+ permutations. We assume that expand_vec_perm_1 has already failed. */
+
+static bool
+expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d)
+{
+ unsigned elt = d->perm[0], nelt2 = d->nelt / 2;
+ enum machine_mode vmode = d->vmode;
+ unsigned char perm2[4];
+ rtx op0 = d->op0;
+ bool ok;
+
+ switch (vmode)
+ {
+ case V4DFmode:
+ case V8SFmode:
+ /* These are special-cased in sse.md so that we can optionally
+ use the vbroadcast instruction. They expand to two insns
+ if the input happens to be in a register. */
+ gcc_unreachable ();
+
+ case V2DFmode:
+ case V2DImode:
+ case V4SFmode:
+ case V4SImode:
+ /* These are always implementable using standard shuffle patterns. */
+ gcc_unreachable ();
+
+ case V8HImode:
+ case V16QImode:
+ /* These can be implemented via interleave. We save one insn by
+ stopping once we have promoted to V4SImode and then use pshufd. */
+ do
+ {
+ optab otab = vec_interleave_low_optab;
+
+ if (elt >= nelt2)
+ {
+ otab = vec_interleave_high_optab;
+ elt -= nelt2;
+ }
+ nelt2 /= 2;
+
+ op0 = expand_binop (vmode, otab, op0, op0, NULL, 0, OPTAB_DIRECT);
+ vmode = get_mode_wider_vector (vmode);
+ op0 = gen_lowpart (vmode, op0);
+ }
+ while (vmode != V4SImode);
+
+ memset (perm2, elt, 4);
+ ok = expand_vselect (gen_lowpart (V4SImode, d->target), op0, perm2, 4);
+ gcc_assert (ok);
+ return true;
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* A subroutine of ix86_expand_vec_perm_builtin_1. Pattern match
+ broadcast permutations. */
+
+static bool
+expand_vec_perm_broadcast (struct expand_vec_perm_d *d)
+{
+ unsigned i, elt, nelt = d->nelt;
+
+ if (d->op0 != d->op1)
+ return false;
+
+ elt = d->perm[0];
+ for (i = 1; i < nelt; ++i)
+ if (d->perm[i] != elt)
+ return false;
+
+ return expand_vec_perm_broadcast_1 (d);
+}
+
/* The guts of ix86_expand_vec_perm_builtin, also used by the ok hook.
With all of the interface bits taken care of, perform the expansion
in D and return true on success. */
@@ -29803,8 +29973,7 @@ expand_vec_perm_even_odd (struct expand_vec_perm_d *d)
static bool
ix86_expand_vec_perm_builtin_1 (struct expand_vec_perm_d *d)
{
- /* First things first -- check if the instruction is implementable
- with a single instruction. */
+ /* Try a single instruction expansion. */
if (expand_vec_perm_1 (d))
return true;
@@ -29819,13 +29988,16 @@ ix86_expand_vec_perm_builtin_1 (struct expand_vec_perm_d *d)
if (expand_vec_perm_interleave2 (d))
return true;
+ if (expand_vec_perm_broadcast (d))
+ return true;
+
/* Try sequences of three instructions. */
if (expand_vec_perm_pshufb2 (d))
return true;
/* ??? Look for narrow permutations whose element orderings would
- allow the promition to a wider mode. */
+ allow the promotion to a wider mode. */
/* ??? Look for sequences of interleave or a wider permute that place
the data into the correct lanes for a half-vector shuffle like
@@ -29837,8 +30009,6 @@ ix86_expand_vec_perm_builtin_1 (struct expand_vec_perm_d *d)
if (expand_vec_perm_even_odd (d))
return true;
- /* ??? Pattern match broadcast. */
-
return false;
}
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index d401f92950f..851061dcd8d 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -747,6 +747,9 @@
;; All single word integer modes.
(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
+;; Single word integer modes without DImode.
+(define_mode_iterator SWI124 [QI HI SI])
+
;; Single word integer modes without QImode.
(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
@@ -21169,18 +21172,14 @@
}
[(set_attr "type" "multi")])
-(define_mode_iterator CRC32MODE [QI HI SI])
-(define_mode_attr crc32modesuffix [(QI "{b}") (HI "{w}") (SI "{l}")])
-(define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
-
(define_insn "sse4_2_crc32<mode>"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI
[(match_operand:SI 1 "register_operand" "0")
- (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
+ (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
UNSPEC_CRC32))]
"TARGET_SSE4_2 || TARGET_CRC32"
- "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
+ "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
[(set_attr "type" "sselog1")
(set_attr "prefix_rep" "1")
(set_attr "prefix_extra" "1")
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 7200a6a2167..8f901cd8754 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -1227,3 +1227,34 @@
(define_predicate "avx_vpermilp_v2df_operand"
(and (match_code "parallel")
(match_test "avx_vpermilp_parallel (op, V2DFmode)")))
+
+;; Return 1 if OP is a parallel for a vperm2f128 permute.
+
+(define_predicate "avx_vperm2f128_v8sf_operand"
+ (and (match_code "parallel")
+ (match_test "avx_vperm2f128_parallel (op, V8SFmode)")))
+
+(define_predicate "avx_vperm2f128_v8si_operand"
+ (and (match_code "parallel")
+ (match_test "avx_vperm2f128_parallel (op, V8SImode)")))
+
+(define_predicate "avx_vperm2f128_v4df_operand"
+ (and (match_code "parallel")
+ (match_test "avx_vperm2f128_parallel (op, V4DFmode)")))
+
+;; Return 1 if OP is a parallel for a vbroadcast permute.
+
+(define_predicate "avx_vbroadcast_operand"
+ (and (match_code "parallel")
+ (match_code "const_int" "a"))
+{
+ rtx elt = XVECEXP (op, 0, 0);
+ int i, nelt = XVECLEN (op, 0);
+
+ /* Don't bother checking there are the right number of operands,
+ merely that they're all identical. */
+ for (i = 1; i < nelt; ++i)
+ if (XVECEXP (op, 0, i) != elt)
+ return false;
+ return true;
+})
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 27c7a8b4842..08a3b5b5c89 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -54,6 +54,7 @@
(define_mode_iterator AVX256MODEF2P [V8SF V4DF])
(define_mode_iterator AVX256MODE2P [V8SI V8SF V4DF])
+(define_mode_iterator AVX256MODE24P [V8SI V8SF V4DI V4DF])
(define_mode_iterator AVX256MODE4P [V4DI V4DF])
(define_mode_iterator AVX256MODE8P [V8SI V8SF])
(define_mode_iterator AVXMODEF2P [V4SF V2DF V8SF V4DF])
@@ -96,6 +97,8 @@
(define_mode_attr ssemodesuffixf2c [(V4SF "s") (V2DF "d")])
+(define_mode_attr ssescalarmodesuffix2s [(V4SF "ss") (V4SI "d")])
+
;; Mapping of the max integer size for xop rotate immediate constraint
(define_mode_attr sserotatemax [(V16QI "7") (V8HI "15") (V4SI "31") (V2DI "63")])
@@ -125,17 +128,18 @@
[(V16QI "V4SF") (V8HI "V4SF") (V4SI "V4SF") (V2DI "V4SF")
(V32QI "V8SF") (V16HI "V8SF") (V8SI "V8SF") (V4DI "V8SF")])
(define_mode_attr avxhalfvecmode
- [(V4SF "V2SF") (V32QI "V16QI") (V16HI "V8HI") (V8SI "V4SI")
- (V4DI "V2DI") (V8SF "V4SF") (V4DF "V2DF")])
+ [(V32QI "V16QI") (V16HI "V8HI") (V8SI "V4SI") (V4DI "V2DI")
+ (V8SF "V4SF") (V4DF "V2DF")
+ (V16QI "V8QI") (V8HI "V4HI") (V4SI "V2SI") (V4SF "V2SF")])
(define_mode_attr avxscalarmode
- [(V16QI "QI") (V8HI "HI") (V4SI "SI") (V4SF "SF") (V2DF "DF")
- (V8SF "SF") (V4DF "DF")])
+ [(V16QI "QI") (V8HI "HI") (V4SI "SI") (V2DI "DI") (V4SF "SF") (V2DF "DF")
+ (V32QI "QI") (V16HI "HI") (V8SI "SI") (V4DI "DI") (V8SF "SF") (V4DF "DF")])
(define_mode_attr avxcvtvecmode
[(V4SF "V4SI") (V8SF "V8SI") (V4SI "V4SF") (V8SI "V8SF")])
(define_mode_attr avxpermvecmode
[(V2DF "V2DI") (V4SF "V4SI") (V4DF "V4DI") (V8SF "V8SI")])
(define_mode_attr avxmodesuffixf2c
- [(V4SF "s") (V2DF "d") (V8SF "s") (V4DF "d")])
+ [(V4SF "s") (V2DF "d") (V8SI "s") (V8SF "s") (V4DI "d") (V4DF "d")])
(define_mode_attr avxmodesuffixp
[(V2DF "pd") (V4SI "si") (V4SF "ps") (V8SF "ps") (V8SI "si")
(V4DF "pd")])
@@ -4012,14 +4016,27 @@
[(set_attr "type" "ssemov")
(set_attr "mode" "SF")])
+(define_expand "vec_dupv4sf"
+ [(set (match_operand:V4SF 0 "register_operand" "")
+ (vec_duplicate:V4SF
+ (match_operand:SF 1 "nonimmediate_operand" "")))]
+ "TARGET_SSE"
+{
+ if (!TARGET_AVX)
+ operands[1] = force_reg (V4SFmode, operands[1]);
+})
+
(define_insn "*vec_dupv4sf_avx"
- [(set (match_operand:V4SF 0 "register_operand" "=x")
+ [(set (match_operand:V4SF 0 "register_operand" "=x,x")
(vec_duplicate:V4SF
- (match_operand:SF 1 "register_operand" "x")))]
+ (match_operand:SF 1 "nonimmediate_operand" "x,m")))]
"TARGET_AVX"
- "vshufps\t{$0, %1, %1, %0|%0, %1, %1, 0}"
- [(set_attr "type" "sselog1")
- (set_attr "length_immediate" "1")
+ "@
+ vshufps\t{$0, %1, %1, %0|%0, %1, %1, 0}
+ vbroadcastss\t{%1, %0|%0, %1}"
+ [(set_attr "type" "sselog1,ssemov")
+ (set_attr "length_immediate" "1,0")
+ (set_attr "prefix_extra" "0,1")
(set_attr "prefix" "vex")
(set_attr "mode" "V4SF")])
@@ -4125,35 +4142,78 @@
DONE;
})
-(define_insn "*vec_setv4sf_0_avx"
- [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,x,m")
- (vec_merge:V4SF
- (vec_duplicate:V4SF
- (match_operand:SF 2 "general_operand" " x,m,*r,x*rfF"))
- (match_operand:V4SF 1 "vector_move_operand" " x,C,C ,0")
+(define_insn "*vec_set<mode>_0_avx"
+ [(set (match_operand:SSEMODE4S 0 "nonimmediate_operand" "=x,x, x,x, x,m")
+ (vec_merge:SSEMODE4S
+ (vec_duplicate:SSEMODE4S
+ (match_operand:<ssescalarmode> 2
+ "general_operand" " x,m,*r,x,*rm,x*rfF"))
+ (match_operand:SSEMODE4S 1 "vector_move_operand" " C,C, C,x, x,0")
(const_int 1)))]
"TARGET_AVX"
"@
- vmovss\t{%2, %1, %0|%0, %1, %2}
- vmovss\t{%2, %0|%0, %2}
+ vinsertps\t{$0xe, %2, %2, %0|%0, %2, %2, 0xe}
+ vmov<ssescalarmodesuffix2s>\t{%2, %0|%0, %2}
vmovd\t{%2, %0|%0, %2}
+ vmovss\t{%2, %1, %0|%0, %1, %2}
+ vpinsrd\t{$0, %2, %1, %0|%0, %1, %2, 0}
+ #"
+ [(set_attr "type" "sselog,ssemov,ssemov,ssemov,sselog,*")
+ (set_attr "prefix_extra" "*,*,*,*,1,*")
+ (set_attr "length_immediate" "*,*,*,*,1,*")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "SF,<ssescalarmode>,SI,SF,TI,*")])
+
+(define_insn "*vec_set<mode>_0_sse4_1"
+ [(set (match_operand:SSEMODE4S 0 "nonimmediate_operand" "=x,x, x,x, x,m")
+ (vec_merge:SSEMODE4S
+ (vec_duplicate:SSEMODE4S
+ (match_operand:<ssescalarmode> 2
+ "general_operand" " x,m,*r,x,*rm,*rfF"))
+ (match_operand:SSEMODE4S 1 "vector_move_operand" " C,C, C,0, 0,0")
+ (const_int 1)))]
+ "TARGET_SSE4_1"
+ "@
+ insertps\t{$0xe, %2, %0|%0, %2, 0xe}
+ mov<ssescalarmodesuffix2s>\t{%2, %0|%0, %2}
+ movd\t{%2, %0|%0, %2}
+ movss\t{%2, %0|%0, %2}
+ pinsrd\t{$0, %2, %0|%0, %2, 0}
+ #"
+ [(set_attr "type" "sselog,ssemov,ssemov,ssemov,sselog,*")
+ (set_attr "prefix_extra" "*,*,*,*,1,*")
+ (set_attr "length_immediate" "*,*,*,*,1,*")
+ (set_attr "mode" "SF,<ssescalarmode>,SI,SF,TI,*")])
+
+(define_insn "*vec_set<mode>_0_sse2"
+ [(set (match_operand:SSEMODE4S 0 "nonimmediate_operand" "=x, x,x,m")
+ (vec_merge:SSEMODE4S
+ (vec_duplicate:SSEMODE4S
+ (match_operand:<ssescalarmode> 2
+ "general_operand" " m,*r,x,x*rfF"))
+ (match_operand:SSEMODE4S 1 "vector_move_operand" " C, C,0,0")
+ (const_int 1)))]
+ "TARGET_SSE2"
+ "@
+ mov<ssescalarmodesuffix2s>\t{%2, %0|%0, %2}
+ movd\t{%2, %0|%0, %2}
+ movss\t{%2, %0|%0, %2}
#"
[(set_attr "type" "ssemov")
- (set_attr "prefix" "vex")
- (set_attr "mode" "SF")])
-
-(define_insn "vec_setv4sf_0"
- [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,Y2,m")
- (vec_merge:V4SF
- (vec_duplicate:V4SF
- (match_operand:SF 2 "general_operand" " x,m,*r,x*rfF"))
- (match_operand:V4SF 1 "vector_move_operand" " 0,C,C ,0")
+ (set_attr "mode" "<ssescalarmode>,SI,SF,*")])
+
+(define_insn "vec_set<mode>_0"
+ [(set (match_operand:SSEMODE4S 0 "nonimmediate_operand" "=x,x,m")
+ (vec_merge:SSEMODE4S
+ (vec_duplicate:SSEMODE4S
+ (match_operand:<ssescalarmode> 2
+ "general_operand" " m,x,x*rfF"))
+ (match_operand:SSEMODE4S 1 "vector_move_operand" " C,0,0")
(const_int 1)))]
"TARGET_SSE"
"@
movss\t{%2, %0|%0, %2}
movss\t{%2, %0|%0, %2}
- movd\t{%2, %0|%0, %2}
#"
[(set_attr "type" "ssemov")
(set_attr "mode" "SF")])
@@ -4484,7 +4544,7 @@
(set_attr "mode" "V4DF")])
(define_expand "vec_interleave_highv2df"
- [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
+ [(set (match_operand:V2DF 0 "register_operand" "")
(vec_select:V2DF
(vec_concat:V4DF
(match_operand:V2DF 1 "nonimmediate_operand" "")
@@ -4492,24 +4552,46 @@
(parallel [(const_int 1)
(const_int 3)])))]
"TARGET_SSE2"
- "ix86_fixup_binary_operands (UNKNOWN, V2DFmode, operands);")
+{
+ if (!ix86_vec_interleave_v2df_operator_ok (operands, 1))
+ operands[2] = force_reg (V2DFmode, operands[2]);
+})
(define_insn "*avx_interleave_highv2df"
- [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
+ [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,m")
(vec_select:V2DF
(vec_concat:V4DF
- (match_operand:V2DF 1 "nonimmediate_operand" " x,o,x")
- (match_operand:V2DF 2 "nonimmediate_operand" " x,x,0"))
+ (match_operand:V2DF 1 "nonimmediate_operand" " x,o,o,x")
+ (match_operand:V2DF 2 "nonimmediate_operand" " x,1,x,0"))
(parallel [(const_int 1)
(const_int 3)])))]
- "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+ "TARGET_AVX && ix86_vec_interleave_v2df_operator_ok (operands, 1)"
"@
vunpckhpd\t{%2, %1, %0|%0, %1, %2}
+ vmovddup\t{%H1, %0|%0, %H1}
vmovlpd\t{%H1, %2, %0|%0, %2, %H1}
vmovhpd\t{%1, %0|%0, %1}"
- [(set_attr "type" "sselog,ssemov,ssemov")
+ [(set_attr "type" "sselog,sselog,ssemov,ssemov")
(set_attr "prefix" "vex")
- (set_attr "mode" "V2DF,V1DF,V1DF")])
+ (set_attr "mode" "V2DF,V2DF,V1DF,V1DF")])
+
+(define_insn "*sse3_interleave_highv2df"
+ [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,m")
+ (vec_select:V2DF
+ (vec_concat:V4DF
+ (match_operand:V2DF 1 "nonimmediate_operand" " 0,o,o,x")
+ (match_operand:V2DF 2 "nonimmediate_operand" " x,1,0,0"))
+ (parallel [(const_int 1)
+ (const_int 3)])))]
+ "TARGET_SSE3 && ix86_vec_interleave_v2df_operator_ok (operands, 1)"
+ "@
+ unpckhpd\t{%2, %0|%0, %2}
+ movddup\t{%H1, %0|%0, %H1}
+ movlpd\t{%H1, %0|%0, %H1}
+ movhpd\t{%1, %0|%0, %1}"
+ [(set_attr "type" "sselog,sselog,ssemov,ssemov")
+ (set_attr "prefix_data16" "*,*,1,1")
+ (set_attr "mode" "V2DF,V2DF,V1DF,V1DF")])
(define_insn "*sse2_interleave_highv2df"
[(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
@@ -4519,7 +4601,7 @@
(match_operand:V2DF 2 "nonimmediate_operand" " x,0,0"))
(parallel [(const_int 1)
(const_int 3)])))]
- "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+ "TARGET_SSE2 && ix86_vec_interleave_v2df_operator_ok (operands, 1)"
"@
unpckhpd\t{%2, %0|%0, %2}
movlpd\t{%H1, %0|%0, %H1}
@@ -4528,85 +4610,48 @@
(set_attr "prefix_data16" "*,1,1")
(set_attr "mode" "V2DF,V1DF,V1DF")])
-(define_insn "avx_movddup256"
- [(set (match_operand:V4DF 0 "register_operand" "=x")
+;; Recall that the 256-bit unpck insns only shuffle within their lanes.
+(define_expand "avx_movddup256"
+ [(set (match_operand:V4DF 0 "register_operand" "")
(vec_select:V4DF
(vec_concat:V8DF
- (match_operand:V4DF 1 "nonimmediate_operand" "xm")
+ (match_operand:V4DF 1 "nonimmediate_operand" "")
(match_dup 1))
- (parallel [(const_int 0) (const_int 2)
- (const_int 4) (const_int 6)])))]
+ (parallel [(const_int 0) (const_int 4)
+ (const_int 2) (const_int 6)])))]
"TARGET_AVX"
- "vmovddup\t{%1, %0|%0, %1}"
- [(set_attr "type" "sselog1")
- (set_attr "prefix" "vex")
- (set_attr "mode" "V4DF")])
-
-(define_insn "*avx_movddup"
- [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,o")
- (vec_select:V2DF
- (vec_concat:V4DF
- (match_operand:V2DF 1 "nonimmediate_operand" "xm,x")
- (match_dup 1))
- (parallel [(const_int 0)
- (const_int 2)])))]
- "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "@
- vmovddup\t{%1, %0|%0, %1}
- #"
- [(set_attr "type" "sselog1,ssemov")
- (set_attr "prefix" "vex")
- (set_attr "mode" "V2DF")])
-
-(define_insn "*sse3_movddup"
- [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,o")
- (vec_select:V2DF
- (vec_concat:V4DF
- (match_operand:V2DF 1 "nonimmediate_operand" "xm,x")
- (match_dup 1))
- (parallel [(const_int 0)
- (const_int 2)])))]
- "TARGET_SSE3 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "@
- movddup\t{%1, %0|%0, %1}
- #"
- [(set_attr "type" "sselog1,ssemov")
- (set_attr "mode" "V2DF")])
-
-(define_split
- [(set (match_operand:V2DF 0 "memory_operand" "")
- (vec_select:V2DF
- (vec_concat:V4DF
- (match_operand:V2DF 1 "register_operand" "")
- (match_dup 1))
- (parallel [(const_int 0)
- (const_int 2)])))]
- "TARGET_SSE3 && reload_completed"
- [(const_int 0)]
-{
- rtx low = gen_rtx_REG (DFmode, REGNO (operands[1]));
- emit_move_insn (adjust_address (operands[0], DFmode, 0), low);
- emit_move_insn (adjust_address (operands[0], DFmode, 8), low);
- DONE;
-})
+ "")
-;; Recall that the 256-bit unpck insns only shuffle within their lanes.
-(define_insn "avx_unpcklpd256"
- [(set (match_operand:V4DF 0 "register_operand" "=x")
+(define_expand "avx_unpcklpd256"
+ [(set (match_operand:V4DF 0 "register_operand" "")
(vec_select:V4DF
(vec_concat:V8DF
- (match_operand:V4DF 1 "register_operand" "x")
- (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
+ (match_operand:V4DF 1 "register_operand" "")
+ (match_operand:V4DF 2 "nonimmediate_operand" ""))
(parallel [(const_int 0) (const_int 4)
(const_int 2) (const_int 6)])))]
"TARGET_AVX"
- "vunpcklpd\t{%2, %1, %0|%0, %1, %2}"
+ "")
+
+(define_insn "*avx_unpcklpd256"
+ [(set (match_operand:V4DF 0 "register_operand" "=x,x")
+ (vec_select:V4DF
+ (vec_concat:V8DF
+ (match_operand:V4DF 1 "nonimmediate_operand" "xm,x")
+ (match_operand:V4DF 2 "nonimmediate_operand" " 1,xm"))
+ (parallel [(const_int 0) (const_int 4)
+ (const_int 2) (const_int 6)])))]
+ "TARGET_AVX
+ && (!MEM_P (operands[1]) || rtx_equal_p (operands[1], operands[2]))"
+ "@
+ vmovddup\t{%1, %0|%0, %1}
+ vunpcklpd\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix" "vex")
(set_attr "mode" "V4DF")])
(define_expand "vec_interleave_lowv2df"
- [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
+ [(set (match_operand:V2DF 0 "register_operand" "")
(vec_select:V2DF
(vec_concat:V4DF
(match_operand:V2DF 1 "nonimmediate_operand" "")
@@ -4614,24 +4659,46 @@
(parallel [(const_int 0)
(const_int 2)])))]
"TARGET_SSE2"
- "ix86_fixup_binary_operands (UNKNOWN, V2DFmode, operands);")
+{
+ if (!ix86_vec_interleave_v2df_operator_ok (operands, 0))
+ operands[1] = force_reg (V2DFmode, operands[1]);
+})
(define_insn "*avx_interleave_lowv2df"
- [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,o")
+ [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,o")
(vec_select:V2DF
(vec_concat:V4DF
- (match_operand:V2DF 1 "nonimmediate_operand" " x,x,0")
- (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x"))
+ (match_operand:V2DF 1 "nonimmediate_operand" " x,m,x,0")
+ (match_operand:V2DF 2 "nonimmediate_operand" " x,1,m,x"))
(parallel [(const_int 0)
(const_int 2)])))]
- "TARGET_AVX && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+ "TARGET_AVX && ix86_vec_interleave_v2df_operator_ok (operands, 0)"
"@
vunpcklpd\t{%2, %1, %0|%0, %1, %2}
+ vmovddup\t{%1, %0|%0, %1}
vmovhpd\t{%2, %1, %0|%0, %1, %2}
vmovlpd\t{%2, %H0|%H0, %2}"
- [(set_attr "type" "sselog,ssemov,ssemov")
+ [(set_attr "type" "sselog,sselog,ssemov,ssemov")
(set_attr "prefix" "vex")
- (set_attr "mode" "V2DF,V1DF,V1DF")])
+ (set_attr "mode" "V2DF,V2DF,V1DF,V1DF")])
+
+(define_insn "*sse3_interleave_lowv2df"
+ [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,o")
+ (vec_select:V2DF
+ (vec_concat:V4DF
+ (match_operand:V2DF 1 "nonimmediate_operand" " 0,m,0,0")
+ (match_operand:V2DF 2 "nonimmediate_operand" " x,1,m,x"))
+ (parallel [(const_int 0)
+ (const_int 2)])))]
+ "TARGET_SSE3 && ix86_vec_interleave_v2df_operator_ok (operands, 0)"
+ "@
+ unpcklpd\t{%2, %0|%0, %2}
+ movddup\t{%1, %0|%0, %1}
+ movhpd\t{%2, %0|%0, %2}
+ movlpd\t{%2, %H0|%H0, %2}"
+ [(set_attr "type" "sselog,sselog,ssemov,ssemov")
+ (set_attr "prefix_data16" "*,*,1,1")
+ (set_attr "mode" "V2DF,V2DF,V1DF,V1DF")])
(define_insn "*sse2_interleave_lowv2df"
[(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,o")
@@ -4641,7 +4708,7 @@
(match_operand:V2DF 2 "nonimmediate_operand" " x,m,x"))
(parallel [(const_int 0)
(const_int 2)])))]
- "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+ "TARGET_SSE2 && ix86_vec_interleave_v2df_operator_ok (operands, 0)"
"@
unpcklpd\t{%2, %0|%0, %2}
movhpd\t{%2, %0|%0, %2}
@@ -4650,6 +4717,37 @@
(set_attr "prefix_data16" "*,1,1")
(set_attr "mode" "V2DF,V1DF,V1DF")])
+(define_split
+ [(set (match_operand:V2DF 0 "memory_operand" "")
+ (vec_select:V2DF
+ (vec_concat:V4DF
+ (match_operand:V2DF 1 "register_operand" "")
+ (match_dup 1))
+ (parallel [(const_int 0)
+ (const_int 2)])))]
+ "TARGET_SSE3 && reload_completed"
+ [(const_int 0)]
+{
+ rtx low = gen_rtx_REG (DFmode, REGNO (operands[1]));
+ emit_move_insn (adjust_address (operands[0], DFmode, 0), low);
+ emit_move_insn (adjust_address (operands[0], DFmode, 8), low);
+ DONE;
+})
+
+(define_split
+ [(set (match_operand:V2DF 0 "register_operand" "")
+ (vec_select:V2DF
+ (vec_concat:V4DF
+ (match_operand:V2DF 1 "memory_operand" "")
+ (match_dup 1))
+ (parallel [(match_operand:SI 2 "const_0_to_1_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")])))]
+ "TARGET_SSE3 && INTVAL (operands[2]) + 2 == INTVAL (operands[3])"
+ [(set (match_dup 0) (vec_duplicate:V2DF (match_dup 1)))]
+{
+ operands[1] = adjust_address (operands[1], DFmode, INTVAL (operands[2]) * 8);
+})
+
(define_expand "avx_shufpd256"
[(match_operand:V4DF 0 "register_operand" "")
(match_operand:V4DF 1 "register_operand" "")
@@ -7408,6 +7506,20 @@
[(set_attr "type" "ssemov")
(set_attr "mode" "V2SF,V4SF,V2SF")])
+(define_insn "*vec_dupv4si_avx"
+ [(set (match_operand:V4SI 0 "register_operand" "=x,x")
+ (vec_duplicate:V4SI
+ (match_operand:SI 1 "register_operand" "x,m")))]
+ "TARGET_AVX"
+ "@
+ vpshufd\t{$0, %1, %0|%0, %1, 0}
+ vbroadcastss\t{%1, %0|%0, %1}"
+ [(set_attr "type" "sselog1,ssemov")
+ (set_attr "length_immediate" "1,0")
+ (set_attr "prefix_extra" "0,1")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "TI,V4SF")])
+
(define_insn "*vec_dupv4si"
[(set (match_operand:V4SI 0 "register_operand" "=Y2,x")
(vec_duplicate:V4SI
@@ -7417,19 +7529,31 @@
%vpshufd\t{$0, %1, %0|%0, %1, 0}
shufps\t{$0, %0, %0|%0, %0, 0}"
[(set_attr "type" "sselog1")
- (set_attr "prefix" "maybe_vex,orig")
(set_attr "length_immediate" "1")
(set_attr "mode" "TI,V4SF")])
(define_insn "*vec_dupv2di_avx"
- [(set (match_operand:V2DI 0 "register_operand" "=x")
+ [(set (match_operand:V2DI 0 "register_operand" "=x,x")
(vec_duplicate:V2DI
- (match_operand:DI 1 "register_operand" "x")))]
+ (match_operand:DI 1 "nonimmediate_operand" " x,m")))]
"TARGET_AVX"
- "vpunpcklqdq\t{%1, %1, %0|%0, %1, %1}"
+ "@
+ vpunpcklqdq\t{%1, %1, %0|%0, %1, %1}
+ vmovddup\t{%1, %0|%0, %1}"
[(set_attr "type" "sselog1")
(set_attr "prefix" "vex")
- (set_attr "mode" "TI")])
+ (set_attr "mode" "TI,DF")])
+
+(define_insn "*vec_dupv2di_sse3"
+ [(set (match_operand:V2DI 0 "register_operand" "=x,x")
+ (vec_duplicate:V2DI
+ (match_operand:DI 1 "nonimmediate_operand" " 0,m")))]
+ "TARGET_SSE3"
+ "@
+ punpcklqdq\t%0, %0
+ movddup\t{%1, %0|%0, %1}"
+ [(set_attr "type" "sselog1")
+ (set_attr "mode" "TI,DF")])
(define_insn "*vec_dupv2di"
[(set (match_operand:V2DI 0 "register_operand" "=Y2,x")
@@ -11838,6 +11962,108 @@
(set_attr "prefix" "vex")
(set_attr "mode" "OI")])
+(define_insn_and_split "vec_dup<mode>"
+ [(set (match_operand:AVX256MODE24P 0 "register_operand" "=x,x")
+ (vec_duplicate:AVX256MODE24P
+ (match_operand:<avxscalarmode> 1 "nonimmediate_operand" "m,?x")))]
+ "TARGET_AVX"
+ "@
+ vbroadcasts<avxmodesuffixf2c>\t{%1, %0|%0, %1}
+ #"
+ "&& reload_completed && REG_P (operands[1])"
+ [(set (match_dup 2) (vec_duplicate:<avxhalfvecmode> (match_dup 1)))
+ (set (match_dup 0) (vec_concat:AVX256MODE24P (match_dup 2) (match_dup 2)))]
+{
+ operands[2] = gen_rtx_REG (<avxhalfvecmode>mode, REGNO (operands[0]));
+}
+ [(set_attr "type" "ssemov")
+ (set_attr "prefix_extra" "1")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "V8SF")])
+
+(define_insn "avx_vbroadcastf128_<mode>"
+ [(set (match_operand:AVX256MODE 0 "register_operand" "=x,x,x")
+ (vec_concat:AVX256MODE
+ (match_operand:<avxhalfvecmode> 1 "nonimmediate_operand" "m,0,?x")
+ (match_dup 1)))]
+ "TARGET_AVX"
+ "@
+ vbroadcastf128\t{%1, %0|%0, %1}
+ vinsertf128\t{$1, %1, %0, %0|%0, %0, %1, 1}
+ vperm2f128\t{$0, %t1, %t1, %0|%0, %t1, %t1, 0}"
+ [(set_attr "type" "ssemov,sselog1,sselog1")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "0,1,1")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "V4SF,V8SF,V8SF")])
+
+;; Recognize broadcast as a vec_select as produced by builtin_vec_perm.
+;; If it so happens that the input is in memory, use vbroadcast.
+;; Otherwise use vpermilp (and in the case of 256-bit modes, vperm2f128).
+(define_insn "*avx_vperm_broadcast_v4sf"
+ [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
+ (vec_select:V4SF
+ (match_operand:V4SF 1 "nonimmediate_operand" "m,o,x")
+ (match_parallel 2 "avx_vbroadcast_operand"
+ [(match_operand 3 "const_int_operand" "C,n,n")])))]
+ "TARGET_AVX"
+{
+ int elt = INTVAL (operands[3]);
+ switch (which_alternative)
+ {
+ case 0:
+ case 1:
+ operands[1] = adjust_address_nv (operands[1], SFmode, elt * 4);
+ return "vbroadcastss\t{%1, %0|%0, %1}";
+ case 2:
+ operands[2] = GEN_INT (elt * 0x55);
+ return "vpermilps\t{%2, %1, %0|%0, %1, %2}";
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "ssemov,ssemov,sselog1")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "0,0,1")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "SF,SF,V4SF")])
+
+(define_insn_and_split "*avx_vperm_broadcast_<mode>"
+ [(set (match_operand:AVX256MODEF2P 0 "register_operand" "=x,x,x")
+ (vec_select:AVX256MODEF2P
+ (match_operand:AVX256MODEF2P 1 "nonimmediate_operand" "m,o,?x")
+ (match_parallel 2 "avx_vbroadcast_operand"
+ [(match_operand 3 "const_int_operand" "C,n,n")])))]
+ "TARGET_AVX"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (vec_duplicate:AVX256MODEF2P (match_dup 1)))]
+{
+ rtx op0 = operands[0], op1 = operands[1];
+ int elt = INTVAL (operands[3]);
+
+ if (REG_P (op1))
+ {
+ int mask;
+
+ /* Shuffle element we care about into all elements of the 128-bit lane.
+ The other lane gets shuffled too, but we don't care. */
+ if (<MODE>mode == V4DFmode)
+ mask = (elt & 1 ? 15 : 0);
+ else
+ mask = (elt & 3) * 0x55;
+ emit_insn (gen_avx_vpermil<mode> (op0, op1, GEN_INT (mask)));
+
+ /* Shuffle the lane we care about into both lanes of the dest. */
+ mask = (elt / (<ssescalarnum> / 2)) * 0x11;
+ emit_insn (gen_avx_vperm2f128<mode>3 (op0, op0, op0, GEN_INT (mask)));
+ DONE;
+ }
+
+ operands[1] = adjust_address_nv (op1, <avxscalarmode>mode,
+ elt * GET_MODE_SIZE (<avxscalarmode>mode));
+})
+
(define_expand "avx_vpermil<mode>"
[(set (match_operand:AVXMODEFDP 0 "register_operand" "")
(vec_select:AVXMODEFDP
@@ -11917,7 +12143,44 @@
(set_attr "prefix" "vex")
(set_attr "mode" "<MODE>")])
-(define_insn "avx_vperm2f128<mode>3"
+(define_expand "avx_vperm2f128<mode>3"
+ [(set (match_operand:AVX256MODE2P 0 "register_operand" "")
+ (unspec:AVX256MODE2P
+ [(match_operand:AVX256MODE2P 1 "register_operand" "")
+ (match_operand:AVX256MODE2P 2 "nonimmediate_operand" "")
+ (match_operand:SI 3 "const_0_to_255_operand" "")]
+ UNSPEC_VPERMIL2F128))]
+ "TARGET_AVX"
+{
+ int mask = INTVAL (operands[2]);
+ if ((mask & 0x88) == 0)
+ {
+ rtx perm[<ssescalarnum>], t1, t2;
+ int i, base, nelt = <ssescalarnum>, nelt2 = nelt / 2;
+
+ base = (mask & 3) * nelt2;
+ for (i = 0; i < nelt2; ++i)
+ perm[i] = GEN_INT (base + i);
+
+ base = ((mask >> 4) & 3) * nelt2;
+ for (i = 0; i < nelt2; ++i)
+ perm[i + nelt2] = GEN_INT (base + i);
+
+ t2 = gen_rtx_VEC_CONCAT (<ssedoublesizemode>mode,
+ operands[1], operands[2]);
+ t1 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelt, perm));
+ t2 = gen_rtx_VEC_SELECT (<MODE>mode, t2, t1);
+ t2 = gen_rtx_SET (VOIDmode, operands[0], t2);
+ emit_insn (t2);
+ DONE;
+ }
+})
+
+;; Note that bits 7 and 3 of the imm8 allow lanes to be zeroed, which
+;; means that in order to represent this properly in rtl we'd have to
+;; nest *another* vec_concat with a zero operand and do the select from
+;; a 4x wide vector. That doesn't seem very nice.
+(define_insn "*avx_vperm2f128<mode>_full"
[(set (match_operand:AVX256MODE2P 0 "register_operand" "=x")
(unspec:AVX256MODE2P
[(match_operand:AVX256MODE2P 1 "register_operand" "x")
@@ -11932,57 +12195,25 @@
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
-(define_insn "avx_vbroadcasts<avxmodesuffixf2c><avxmodesuffix>"
- [(set (match_operand:AVXMODEF4P 0 "register_operand" "=x")
- (vec_concat:AVXMODEF4P
- (vec_concat:<avxhalfvecmode>
- (match_operand:<avxscalarmode> 1 "memory_operand" "m")
- (match_dup 1))
- (vec_concat:<avxhalfvecmode>
- (match_dup 1)
- (match_dup 1))))]
- "TARGET_AVX"
- "vbroadcasts<avxmodesuffixf2c>\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssemov")
- (set_attr "prefix_extra" "1")
- (set_attr "prefix" "vex")
- (set_attr "mode" "<avxscalarmode>")])
-
-(define_insn "avx_vbroadcastss256"
- [(set (match_operand:V8SF 0 "register_operand" "=x")
- (vec_concat:V8SF
- (vec_concat:V4SF
- (vec_concat:V2SF
- (match_operand:SF 1 "memory_operand" "m")
- (match_dup 1))
- (vec_concat:V2SF
- (match_dup 1)
- (match_dup 1)))
- (vec_concat:V4SF
- (vec_concat:V2SF
- (match_dup 1)
- (match_dup 1))
- (vec_concat:V2SF
- (match_dup 1)
- (match_dup 1)))))]
- "TARGET_AVX"
- "vbroadcastss\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssemov")
- (set_attr "prefix_extra" "1")
- (set_attr "prefix" "vex")
- (set_attr "mode" "SF")])
-
-(define_insn "avx_vbroadcastf128_p<avxmodesuffixf2c>256"
- [(set (match_operand:AVX256MODEF2P 0 "register_operand" "=x")
- (vec_concat:AVX256MODEF2P
- (match_operand:<avxhalfvecmode> 1 "memory_operand" "m")
- (match_dup 1)))]
+(define_insn "*avx_vperm2f128<mode>_nozero"
+ [(set (match_operand:AVX256MODE2P 0 "register_operand" "=x")
+ (vec_select:AVX256MODE2P
+ (vec_concat:<ssedoublesizemode>
+ (match_operand:AVX256MODE2P 1 "register_operand" "x")
+ (match_operand:AVX256MODE2P 2 "nonimmediate_operand" "xm"))
+ (match_parallel 3 "avx_vperm2f128_<mode>_operand"
+ [(match_operand 4 "const_int_operand" "")])))]
"TARGET_AVX"
- "vbroadcastf128\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssemov")
+{
+ int mask = avx_vperm2f128_parallel (operands[3], <MODE>mode) - 1;
+ operands[3] = GEN_INT (mask);
+ return "vperm2f128\t{%3, %2, %1, %0|%0, %1, %2, %3}";
+}
+ [(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
- (set_attr "mode" "V4SF")])
+ (set_attr "mode" "V8SF")])
(define_expand "avx_vinsertf128<mode>"
[(match_operand:AVX256MODE 0 "register_operand" "")
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index f8dcaa9673a..a6bd1e4f739 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -603,6 +603,64 @@ i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
export_head = p;
}
+#ifdef CXX_WRAP_SPEC_LIST
+
+/* Hash table equality helper function. */
+
+static int
+wrapper_strcmp (const void *x, const void *y)
+{
+ return !strcmp ((const char *) x, (const char *) y);
+}
+
+/* Search for a function named TARGET in the list of library wrappers
+ we are using, returning a pointer to it if found or NULL if not.
+ This function might be called on quite a few symbols, and we only
+ have the list of names of wrapped functions available to us as a
+ spec string, so first time round we lazily initialise a hash table
+ to make things quicker. */
+
+static const char *
+i386_find_on_wrapper_list (const char *target)
+{
+ static char first_time = 1;
+ static htab_t wrappers;
+
+ if (first_time)
+ {
+ /* Beware that this is not a complicated parser, it assumes
+ that any sequence of non-whitespace beginning with an
+ underscore is one of the wrapped symbols. For now that's
+ adequate to distinguish symbols from spec substitutions
+ and command-line options. */
+ static char wrapper_list_buffer[] = CXX_WRAP_SPEC_LIST;
+ char *bufptr;
+ /* Breaks up the char array into separated strings
+ strings and enter them into the hash table. */
+ wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp,
+ 0, xcalloc, free);
+ for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
+ {
+ char *found = NULL;
+ if (ISSPACE (*bufptr))
+ continue;
+ if (*bufptr == '_')
+ found = bufptr;
+ while (*bufptr && !ISSPACE (*bufptr))
+ ++bufptr;
+ if (*bufptr)
+ *bufptr = 0;
+ if (found)
+ *htab_find_slot (wrappers, found, INSERT) = found;
+ }
+ first_time = 0;
+ }
+
+ return (const char *) htab_find (wrappers, target);
+}
+
+#endif /* CXX_WRAP_SPEC_LIST */
+
/* This is called at the end of assembly. For each external function
which has not been defined, we output a declaration now. We also
output the .drectve section. */
@@ -624,6 +682,15 @@ i386_pe_file_end (void)
if (! TREE_ASM_WRITTEN (decl)
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
{
+#ifdef CXX_WRAP_SPEC_LIST
+ /* To ensure the DLL that provides the corresponding real
+ functions is still loaded at runtime, we must reference
+ the real function so that an (unused) import is created. */
+ const char *realsym = i386_find_on_wrapper_list (p->name);
+ if (realsym)
+ i386_pe_declare_function_type (asm_out_file,
+ concat ("__real_", realsym, NULL), TREE_PUBLIC (decl));
+#endif /* CXX_WRAP_SPEC_LIST */
TREE_ASM_WRITTEN (decl) = 1;
i386_pe_declare_function_type (asm_out_file, p->name,
TREE_PUBLIC (decl));
diff --git a/gcc/config/i386/x86intrin.h b/gcc/config/i386/x86intrin.h
index ac7e21fd6f7..63252bf95c8 100644
--- a/gcc/config/i386/x86intrin.h
+++ b/gcc/config/i386/x86intrin.h
@@ -77,4 +77,8 @@
#include <lwpintrin.h>
#endif
+#ifdef __ABM__
+#include <abmintrin.h>
+#endif
+
#endif /* _X86INTRIN_H_INCLUDED */
diff --git a/gcc/config/mips/mips-dsp.md b/gcc/config/mips/mips-dsp.md
index ff2004ccb54..dd2459ebcaf 100644
--- a/gcc/config/mips/mips-dsp.md
+++ b/gcc/config/mips/mips-dsp.md
@@ -1066,7 +1066,7 @@
(define_insn "mips_lhx_<mode>"
[(set (match_operand:SI 0 "register_operand" "=d")
- (zero_extend:SI
+ (sign_extend:SI
(mem:HI (plus:P (match_operand:P 1 "register_operand" "d")
(match_operand:P 2 "register_operand" "d")))))]
"ISA_HAS_DSP"
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index 8157221c0c6..7335efcd0a1 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -163,7 +163,7 @@ extern rtx sh_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
extern void sh_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
extern int sh_pass_in_reg_p (CUMULATIVE_ARGS *, enum machine_mode, tree);
extern void sh_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, signed int, enum machine_mode);
-extern bool sh_promote_prototypes (const_tree);
+extern bool sh_function_value_regno_p (const unsigned int);
extern rtx sh_dwarf_register_span (rtx);
extern rtx replace_n_hard_rtx (rtx, rtx *, int , int);
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 26bceea670d..5fe752eac20 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -251,6 +251,8 @@ static struct save_entry_s *sh5_schedule_saves (HARD_REG_SET *,
struct save_schedule_s *, int);
static rtx sh_struct_value_rtx (tree, int);
+static rtx sh_function_value (const_tree, const_tree, bool);
+static rtx sh_libcall_value (enum machine_mode, const_rtx);
static bool sh_return_in_memory (const_tree, const_tree);
static rtx sh_builtin_saveregs (void);
static void sh_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int);
@@ -259,6 +261,7 @@ static bool sh_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);
static tree sh_build_builtin_va_list (void);
static void sh_va_start (tree, rtx);
static tree sh_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
+static bool sh_promote_prototypes (const_tree);
static enum machine_mode sh_promote_function_mode (const_tree type,
enum machine_mode,
int *punsignedp,
@@ -451,6 +454,10 @@ static const struct attribute_spec sh_attribute_table[] =
#undef TARGET_PROMOTE_FUNCTION_MODE
#define TARGET_PROMOTE_FUNCTION_MODE sh_promote_function_mode
+#undef TARGET_FUNCTION_VALUE
+#define TARGET_FUNCTION_VALUE sh_function_value
+#undef TARGET_LIBCALL_VALUE
+#define TARGET_LIBCALL_VALUE sh_libcall_value
#undef TARGET_STRUCT_VALUE_RTX
#define TARGET_STRUCT_VALUE_RTX sh_struct_value_rtx
#undef TARGET_RETURN_IN_MEMORY
@@ -7947,7 +7954,7 @@ sh_promote_function_mode (const_tree type, enum machine_mode mode,
return mode;
}
-bool
+static bool
sh_promote_prototypes (const_tree type)
{
if (TARGET_HITACHI)
@@ -8306,6 +8313,54 @@ sh_struct_value_rtx (tree fndecl, int incoming ATTRIBUTE_UNUSED)
return gen_rtx_REG (Pmode, 2);
}
+/* Worker function for TARGET_FUNCTION_VALUE.
+
+ For the SH, this is like LIBCALL_VALUE, except that we must change the
+ mode like PROMOTE_MODE does.
+ ??? PROMOTE_MODE is ignored for non-scalar types. The set of types
+ tested here has to be kept in sync with the one in explow.c:promote_mode.
+*/
+
+static rtx
+sh_function_value (const_tree valtype,
+ const_tree fn_decl_or_type,
+ bool outgoing ATTRIBUTE_UNUSED)
+{
+ if (fn_decl_or_type
+ && !DECL_P (fn_decl_or_type))
+ fn_decl_or_type = NULL;
+
+ return gen_rtx_REG (
+ ((GET_MODE_CLASS (TYPE_MODE (valtype)) == MODE_INT
+ && GET_MODE_SIZE (TYPE_MODE (valtype)) < 4
+ && (TREE_CODE (valtype) == INTEGER_TYPE
+ || TREE_CODE (valtype) == ENUMERAL_TYPE
+ || TREE_CODE (valtype) == BOOLEAN_TYPE
+ || TREE_CODE (valtype) == REAL_TYPE
+ || TREE_CODE (valtype) == OFFSET_TYPE))
+ && sh_promote_prototypes (fn_decl_or_type)
+ ? (TARGET_SHMEDIA64 ? DImode : SImode) : TYPE_MODE (valtype)),
+ BASE_RETURN_VALUE_REG (TYPE_MODE (valtype)));
+}
+
+/* Worker function for TARGET_LIBCALL_VALUE. */
+
+static rtx
+sh_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
+{
+ return gen_rtx_REG (mode, BASE_RETURN_VALUE_REG (mode));
+}
+
+/* Worker function for FUNCTION_VALUE_REGNO_P. */
+
+bool
+sh_function_value_regno_p (const unsigned int regno)
+{
+ return ((regno) == FIRST_RET_REG
+ || (TARGET_SH2E && (regno) == FIRST_FP_RET_REG)
+ || (TARGET_SHMEDIA_FPU && (regno) == FIRST_FP_RET_REG));
+}
+
/* Worker function for TARGET_RETURN_IN_MEMORY. */
static bool
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index c24555f9796..697138f57ce 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -1453,37 +1453,7 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
? FIRST_FP_PARM_REG \
: FIRST_PARM_REG)
-/* Define how to find the value returned by a function.
- VALTYPE is the data type of the value (as a tree).
- If the precise function being called is known, FUNC is its FUNCTION_DECL;
- otherwise, FUNC is 0.
- For the SH, this is like LIBCALL_VALUE, except that we must change the
- mode like PROMOTE_MODE does.
- ??? PROMOTE_MODE is ignored for non-scalar types. The set of types
- tested here has to be kept in sync with the one in explow.c:promote_mode. */
-
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
- gen_rtx_REG ( \
- ((GET_MODE_CLASS (TYPE_MODE (VALTYPE)) == MODE_INT \
- && GET_MODE_SIZE (TYPE_MODE (VALTYPE)) < 4 \
- && (TREE_CODE (VALTYPE) == INTEGER_TYPE \
- || TREE_CODE (VALTYPE) == ENUMERAL_TYPE \
- || TREE_CODE (VALTYPE) == BOOLEAN_TYPE \
- || TREE_CODE (VALTYPE) == REAL_TYPE \
- || TREE_CODE (VALTYPE) == OFFSET_TYPE)) \
- && sh_promote_prototypes (FUNC) \
- ? (TARGET_SHMEDIA64 ? DImode : SImode) : TYPE_MODE (VALTYPE)), \
- BASE_RETURN_VALUE_REG (TYPE_MODE (VALTYPE)))
-
-/* Define how to find the value returned by a library function
- assuming the value has mode MODE. */
-#define LIBCALL_VALUE(MODE) \
- gen_rtx_REG ((MODE), BASE_RETURN_VALUE_REG (MODE));
-
-/* 1 if N is a possible register number for a function value. */
-#define FUNCTION_VALUE_REGNO_P(REGNO) \
- ((REGNO) == FIRST_RET_REG || (TARGET_SH2E && (REGNO) == FIRST_FP_RET_REG) \
- || (TARGET_SHMEDIA_FPU && (REGNO) == FIRST_FP_RET_REG))
+#define FUNCTION_VALUE_REGNO_P(REGNO) sh_function_value_regno_p (REGNO)
/* 1 if N is a possible register number for function argument passing. */
/* ??? There are some callers that pass REGNO as int, and others that pass
diff --git a/gcc/config/stormy16/stormy16-lib2-count-leading-zeros.c b/gcc/config/stormy16/stormy16-lib2-count-leading-zeros.c
deleted file mode 100644
index 1b98d30c18b..00000000000
--- a/gcc/config/stormy16/stormy16-lib2-count-leading-zeros.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define XSTORMY16_COUNT_LEADING_ZEROS
-#include "stormy16-lib2.c"
diff --git a/gcc/config/stormy16/stormy16-lib2.c b/gcc/config/stormy16/stormy16-lib2.c
index 91c3c3dd2ca..0c99cdd3e90 100644
--- a/gcc/config/stormy16/stormy16-lib2.c
+++ b/gcc/config/stormy16/stormy16-lib2.c
@@ -253,14 +253,24 @@ __parityhi2 (UHWtype x)
#endif
#ifdef XSTORMY16_CLZHI2
-/* Returns the number of leading zero bits in X.
- FIXME: The return type really should be "unsigned int"
- but this is not how the builtin is prototyped. */
-
+/* Returns the number of zero-bits from the most significant bit to the
+ first nonzero bit in X. Returns 16 for X == 0. Implemented as a
+ simple for loop in order to save space by removing the need for
+ the __clz_tab array.
+ FIXME: The return type really should be "unsigned int" but this is
+ not how the builtin is prototyped. */
+#undef unsigned
int
__clzhi2 (UHWtype x)
{
- return __stormy16_count_leading_zeros (x);
+ unsigned int i;
+ unsigned int c;
+ unsigned int value = x;
+
+ for (c = 0, i = 1 << 15; i; i >>= 1, c++)
+ if (i & value)
+ break;
+ return c;
}
#endif
@@ -278,7 +288,7 @@ __ctzhi2 (UHWtype x)
bits. */
x &= - x;
- return 15 - __stormy16_count_leading_zeros (x);
+ return 15 - __builtin_clz (x);
}
#endif
@@ -296,26 +306,6 @@ __ffshi2 (UHWtype u)
if (u == 0)
return 0;
- return 16 - __stormy16_count_leading_zeros (u & - u);
+ return 16 - __builtin_clz (u & - u);
}
#endif
-
-#ifdef XSTORMY16_COUNT_LEADING_ZEROS
-#undef unsigned
-/* Count the number of zero-bits from the most significant bit to the
- first nonzero bit in VALUE. Returns 16 for VALUE == 0. Implemented
- as a simple for loop in order to save space by removing the need for
- the __clz_tab array. */
-
-unsigned int
-__stormy16_count_leading_zeros (unsigned int value)
-{
- unsigned int i;
- unsigned int c;
-
- for (c = 0, i = 1 << 15; i; i >>= 1, c++)
- if (i & value)
- break;
- return c;
-}
-#endif /* XSTORMY16_COUNT_LEADING_ZEROS */
diff --git a/gcc/config/stormy16/t-stormy16 b/gcc/config/stormy16/t-stormy16
index b103f88a1df..8959e64ab5e 100644
--- a/gcc/config/stormy16/t-stormy16
+++ b/gcc/config/stormy16/t-stormy16
@@ -18,8 +18,7 @@
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
-# SImode routines
-
+# SImode arithmetic and logical routines, HImode bit counting routines.
LIB2FUNCS_EXTRA = \
$(srcdir)/config/stormy16/stormy16-lib2-udivmodsi4.c \
$(srcdir)/config/stormy16/stormy16-lib2-divsi3.c \
@@ -33,12 +32,9 @@ LIB2FUNCS_EXTRA = \
$(srcdir)/config/stormy16/stormy16-lib2-parityhi2.c \
$(srcdir)/config/stormy16/stormy16-lib2-clzhi2.c \
$(srcdir)/config/stormy16/stormy16-lib2-ctzhi2.c \
- $(srcdir)/config/stormy16/stormy16-lib2-ffshi2.c \
- $(srcdir)/config/stormy16/stormy16-lib2-count-leading-zeros.c
-
-
-# floating point emulation libraries
+ $(srcdir)/config/stormy16/stormy16-lib2-ffshi2.c
+# Floating point emulation libraries.
FPBIT = fp-bit.c
DPBIT = dp-bit.c
diff --git a/gcc/configure b/gcc/configure
index 1ea172a0d35..ec8d682425a 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -22705,6 +22705,32 @@ fi
i[34567]86-*-* | x86_64-*-*)
case $target_os in
+ cygwin*)
+ # Full C++ conformance when using a shared libstdc++-v3 requires some
+ # support from the Cygwin DLL, which in more recent versions exports
+ # wrappers to aid in interposing and redirecting operators new, delete,
+ # etc., as per n2800 #17.6.4.6 [replacement.functions]. Check if we
+ # are configuring for a version of Cygwin that exports the wrappers.
+ if test x$host = x$target; then
+ ac_fn_c_check_func "$LINENO" "__wrap__Znaj" "ac_cv_func___wrap__Znaj"
+if test "x$ac_cv_func___wrap__Znaj" = x""yes; then :
+ gcc_ac_cygwin_dll_wrappers=yes
+else
+ gcc_ac_cygwin_dll_wrappers=no
+fi
+
+ else
+ # Can't check presence of libc functions during cross-compile, so
+ # we just have to assume we're building for an up-to-date target.
+ gcc_ac_cygwin_dll_wrappers=yes
+ fi
+
+cat >>confdefs.h <<_ACEOF
+#define USE_CYGWIN_LIBSTDCXX_WRAPPERS `if test $gcc_ac_cygwin_dll_wrappers = yes; then echo 1; else echo 0; fi`
+_ACEOF
+
+ esac
+ case $target_os in
cygwin* | pe | mingw32*)
# Recent binutils allows the three-operand form of ".comm" on PE. This
# definition is used unconditionally to initialise the default state of
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 17cfe835b8c..5accd597c91 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -3000,6 +3000,25 @@ changequote(,)dnl
i[34567]86-*-* | x86_64-*-*)
changequote([,])dnl
case $target_os in
+ cygwin*)
+ # Full C++ conformance when using a shared libstdc++-v3 requires some
+ # support from the Cygwin DLL, which in more recent versions exports
+ # wrappers to aid in interposing and redirecting operators new, delete,
+ # etc., as per n2800 #17.6.4.6 [replacement.functions]. Check if we
+ # are configuring for a version of Cygwin that exports the wrappers.
+ if test x$host = x$target; then
+ AC_CHECK_FUNC([__wrap__Znaj],[gcc_ac_cygwin_dll_wrappers=yes],[gcc_ac_cygwin_dll_wrappers=no])
+ else
+ # Can't check presence of libc functions during cross-compile, so
+ # we just have to assume we're building for an up-to-date target.
+ gcc_ac_cygwin_dll_wrappers=yes
+ fi
+ AC_DEFINE_UNQUOTED(USE_CYGWIN_LIBSTDCXX_WRAPPERS,
+ [`if test $gcc_ac_cygwin_dll_wrappers = yes; then echo 1; else echo 0; fi`],
+ [Define if you want to generate code by default that assumes that the
+ Cygwin DLL exports wrappers to support libstdc++ function replacement.])
+ esac
+ case $target_os in
cygwin* | pe | mingw32*)
# Recent binutils allows the three-operand form of ".comm" on PE. This
# definition is used unconditionally to initialise the default state of
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 57ce3cd58ff..3a086021776 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,37 @@
+2009-12-01 Taras Glek <taras@mozilla.com>
+
+ * parser.c (cp_parser_class_specifier): Set class location to that
+ of IDENTIFIER_NODE instead of '{' when possible.
+
+2009-12-01 Taras Glek <taras@mozilla.com>
+
+ * semantics.c (begin_class_definition): Do not overide locations with less precise ones.
+
+2009-12-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/41611
+ * decl2.c (get_guard): Copy DECL_COMDAT.
+ (comdat_linkage): Set DECL_COMDAT unconditionally.
+
+2009-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/3187
+ * optimize.c (cdtor_comdat_group): New function.
+ (maybe_clone_body): Also optimize DECL_COMDAT base/complete cdtors
+ and in that case put also the deleting dtor in the same comdat group
+ as base and complete dtor if dtor is virtual.
+
+2009-11-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/40371
+ * call.c (add_template_candidate_real): Early return NULL if
+ the arglist length is smaller than skip_without_in_chrg; tidy.
+
+2009-11-30 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42069
+ * pt.c (convert_template_argument): Strip typedefs from SCOPE_REFs.
+
2009-11-29 Dodji Seketeli <dodji@redhat.com>
PR c++/36408
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 70a5b1efbf5..837a65d8079 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -2457,9 +2457,10 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
{
int ntparms = DECL_NTPARMS (tmpl);
tree targs = make_tree_vec (ntparms);
- unsigned int nargs;
- int skip_without_in_chrg;
- tree first_arg_without_in_chrg;
+ unsigned int len = VEC_length (tree, arglist);
+ unsigned int nargs = (first_arg == NULL_TREE ? 0 : 1) + len;
+ unsigned int skip_without_in_chrg = 0;
+ tree first_arg_without_in_chrg = first_arg;
tree *args_without_in_chrg;
unsigned int nargs_without_in_chrg;
unsigned int ia, ix;
@@ -2468,12 +2469,6 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
int i;
tree fn;
- nargs = (first_arg == NULL_TREE ? 0 : 1) + VEC_length (tree, arglist);
-
- skip_without_in_chrg = 0;
-
- first_arg_without_in_chrg = first_arg;
-
/* We don't do deduction on the in-charge parameter, the VTT
parameter or 'this'. */
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (tmpl))
@@ -2494,9 +2489,11 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
++skip_without_in_chrg;
}
+ if (len < skip_without_in_chrg)
+ return NULL;
+
nargs_without_in_chrg = ((first_arg_without_in_chrg != NULL_TREE ? 1 : 0)
- + (VEC_length (tree, arglist)
- - skip_without_in_chrg));
+ + (len - skip_without_in_chrg));
args_without_in_chrg = XALLOCAVEC (tree, nargs_without_in_chrg);
ia = 0;
if (first_arg_without_in_chrg != NULL_TREE)
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index c0febad2515..1cd2ded03a3 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1574,8 +1574,7 @@ comdat_linkage (tree decl)
}
}
- if (DECL_LANG_SPECIFIC (decl))
- DECL_COMDAT (decl) = 1;
+ DECL_COMDAT (decl) = 1;
}
/* For win32 we also want to put explicit instantiations in
@@ -2555,6 +2554,7 @@ get_guard (tree decl)
TREE_PUBLIC (guard) = TREE_PUBLIC (decl);
TREE_STATIC (guard) = TREE_STATIC (decl);
DECL_COMMON (guard) = DECL_COMMON (decl);
+ DECL_COMDAT (guard) = DECL_COMDAT (decl);
DECL_COMDAT_GROUP (guard) = DECL_COMDAT_GROUP (decl);
if (TREE_PUBLIC (decl))
DECL_WEAK (guard) = DECL_WEAK (decl);
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index 838a7305a71..5a67431cc1f 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -142,6 +142,46 @@ build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
}
}
+/* Return name of comdat group for complete and base ctor (or dtor)
+ that have the same body. If dtor is virtual, deleting dtor goes
+ into this comdat group as well. */
+
+static tree
+cdtor_comdat_group (tree complete, tree base)
+{
+ tree complete_name = DECL_COMDAT_GROUP (complete);
+ tree base_name = DECL_COMDAT_GROUP (base);
+ char *grp_name;
+ const char *p, *q;
+ bool diff_seen = false;
+ size_t idx;
+ if (complete_name == NULL)
+ complete_name = cxx_comdat_group (complete);
+ if (base_name == NULL)
+ base_name = cxx_comdat_group (base);
+ gcc_assert (IDENTIFIER_LENGTH (complete_name)
+ == IDENTIFIER_LENGTH (base_name));
+ grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
+ p = IDENTIFIER_POINTER (complete_name);
+ q = IDENTIFIER_POINTER (base_name);
+ for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
+ if (p[idx] == q[idx])
+ grp_name[idx] = p[idx];
+ else
+ {
+ gcc_assert (!diff_seen
+ && idx > 0
+ && (p[idx - 1] == 'C' || p[idx - 1] == 'D')
+ && p[idx] == '1'
+ && q[idx] == '2');
+ grp_name[idx] = '5';
+ diff_seen = true;
+ }
+ grp_name[idx] = '\0';
+ gcc_assert (diff_seen);
+ return get_identifier (grp_name);
+}
+
/* FN is a function that has a complete body. Clone the body as
necessary. Returns nonzero if there's no longer any need to
process the main body. */
@@ -149,6 +189,7 @@ build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
bool
maybe_clone_body (tree fn)
{
+ tree comdat_group = NULL_TREE;
tree clone;
tree fns[3];
bool first = true;
@@ -248,10 +289,26 @@ maybe_clone_body (tree fn)
&& idx == 1
&& !flag_use_repository
&& DECL_INTERFACE_KNOWN (fns[0])
- && !DECL_ONE_ONLY (fns[0])
+ && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fns[0]))
+ && (!DECL_ONE_ONLY (fns[0])
+ || (HAVE_COMDAT_GROUP
+ && DECL_WEAK (fns[0])
+ /* Don't optimize synthetized virtual dtors, because then
+ the deleting and other dtors are emitted when needed
+ and so it is not certain we would emit both
+ deleting and complete/base dtors in the comdat group. */
+ && (fns[2] == NULL || !DECL_ARTIFICIAL (fn))))
&& cgraph_same_body_alias (clone, fns[0]))
{
alias = true;
+ if (DECL_ONE_ONLY (fns[0]))
+ {
+ /* For comdat base and complete cdtors put them
+ into the same, *[CD]5* comdat group instead of
+ *[CD][12]*. */
+ comdat_group = cdtor_comdat_group (fns[1], fns[0]);
+ DECL_COMDAT_GROUP (fns[0]) = comdat_group;
+ }
emit_associated_thunks (clone);
}
@@ -333,6 +390,15 @@ maybe_clone_body (tree fn)
}
pop_from_top_level ();
+ if (comdat_group)
+ {
+ DECL_COMDAT_GROUP (fns[1]) = comdat_group;
+ if (fns[2])
+ /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
+ virtual, it goes into the same comdat group as well. */
+ DECL_COMDAT_GROUP (fns[2]) = comdat_group;
+ }
+
/* We don't need to process the original function any further. */
return 1;
}
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 5c8dbcb155e..f50d1c0bb8d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -16388,6 +16388,8 @@ cp_parser_class_head (cp_parser* parser,
end_specialization ();
--parser->num_template_parameter_lists;
}
+
+ DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
*attributes_p = attributes;
return type;
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index dd86ceeb682..9fd06b3433f 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5526,6 +5526,13 @@ convert_template_argument (tree parm,
if (TYPE_P (val))
val = strip_typedefs (val);
}
+ else if (TREE_CODE (orig_arg) == SCOPE_REF)
+ {
+ /* Strip typedefs from the SCOPE_REF. */
+ tree type = strip_typedefs (TREE_TYPE (orig_arg));
+ tree scope = strip_typedefs (TREE_OPERAND (orig_arg, 0));
+ val = build2 (SCOPE_REF, type, scope, TREE_OPERAND (orig_arg, 1));
+ }
else
{
tree t = tsubst (TREE_TYPE (parm), args, complain, in_decl);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 4a9bee71624..aa79b22a33f 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2386,9 +2386,6 @@ begin_class_definition (tree t, tree attributes)
pushtag (make_anon_name (), t, /*tag_scope=*/ts_current);
}
- /* Update the location of the decl. */
- DECL_SOURCE_LOCATION (TYPE_NAME (t)) = input_location;
-
if (TYPE_BEING_DEFINED (t))
{
t = make_class_type (TREE_CODE (t));
diff --git a/gcc/doc/contrib.texi b/gcc/doc/contrib.texi
index 6ee5b5001d7..1515b5c876d 100644
--- a/gcc/doc/contrib.texi
+++ b/gcc/doc/contrib.texi
@@ -326,6 +326,10 @@ Stu Grossman for gdb hacking, allowing GCJ developers to debug Java code.
Michael K. Gschwind contributed the port to the PDP-11.
@item
+Richard Guenther for his ongoing middle-end contributions and bug fixes
+and for release management.
+
+@item
Ron Guilmette implemented the @command{protoize} and @command{unprotoize}
tools, the support for Dwarf symbolic debugging information, and much of
the support for System V Release 4. He has also worked heavily on the
diff --git a/gcc/doc/plugins.texi b/gcc/doc/plugins.texi
index eb1008e8f2c..8aac0f7b65c 100644
--- a/gcc/doc/plugins.texi
+++ b/gcc/doc/plugins.texi
@@ -156,18 +156,42 @@ enum plugin_event
PLUGIN_ATTRIBUTES, /* Called during attribute registration */
PLUGIN_START_UNIT, /* Called before processing a translation unit. */
PLUGIN_PRAGMAS, /* Called during pragma registration. */
- PLUGIN_EVENT_LAST /* Dummy event used for indexing callback
+ /* Called before first pass from all_passes. */
+ PLUGIN_ALL_PASSES_START,
+ /* Called after last pass from all_passes. */
+ PLUGIN_ALL_PASSES_END,
+ /* Called before first ipa pass. */
+ PLUGIN_ALL_IPA_PASSES_START,
+ /* Called after last ipa pass. */
+ PLUGIN_ALL_IPA_PASSES_END,
+ /* Allows to override pass gate decision for current_pass. */
+ PLUGIN_OVERRIDE_GATE,
+ /* Called before executing a pass. */
+ PLUGIN_PASS_EXECUTION,
+ /* Called before executing subpasses of a GIMPLE_PASS in
+ execute_ipa_pass_list. */
+ PLUGIN_EARLY_GIMPLE_PASSES_START,
+ /* Called after executing subpasses of a GIMPLE_PASS in
+ execute_ipa_pass_list. */
+ PLUGIN_EARLY_GIMPLE_PASSES_END,
+ /* Called when a pass is first instantiated. */
+ PLUGIN_NEW_PASS,
+
+ PLUGIN_EVENT_FIRST_DYNAMIC /* Dummy event used for indexing callback
array. */
@};
@end smallexample
+In addition, plugins can also look up the enumerator of a named event,
+and / or generate new events dynamically, by calling the function
+@code{get_named_event_id}.
To register a callback, the plugin calls @code{register_callback} with
the arguments:
@itemize
@item @code{char *name}: Plugin name.
-@item @code{enum plugin_event event}: The event code.
+@item @code{int event}: The event code.
@item @code{plugin_callback_func callback}: The function that handles @code{event}.
@item @code{void *user_data}: Pointer to plugin-specific data.
@end itemize
@@ -337,6 +361,41 @@ It is suggested to pass @code{"GCCPLUGIN"} (or a short name identifying
your plugin) as the ``space'' argument of your pragma.
+@section Recording information about pass execution
+
+The event PLUGIN_PASS_EXECUTION passes the pointer to the executed pass
+(the same as current_pass) as @code{gcc_data} to the callback. You can also
+inspect cfun to find out about which function this pass is executed for.
+Note that this event will only be invoked if the gate check (if
+applicable, modified by PLUGIN_OVERRIDE_GATE) succeeds.
+You can use other hooks, like @code{PLUGIN_ALL_PASSES_START},
+@code{PLUGIN_ALL_PASSES_END}, @code{PLUGIN_ALL_IPA_PASSES_START},
+@code{PLUGIN_ALL_IPA_PASSES_END}, @code{PLUGIN_EARLY_GIMPLE_PASSES_START},
+and/or @code{PLUGIN_EARLY_GIMPLE_PASSES_END} to manipulate global state
+in your plugin(s) in order to get context for the pass execution.
+
+
+@section Controlling which passes are being run
+
+After the original gate function for a pass is called, its result
+- the gate status - is stored as an integer.
+Then the event @code{PLUGIN_OVERRIDE_GATE} is invoked, with a pointer
+to the gate status in the @code{gcc_data} parameter to the callback function.
+A nonzero value of the gate status means that the pass is to be executed.
+You can both read and write the gate status via the passed pointer.
+
+
+@section Keeping track of available passes
+
+When your plugin is loaded, you can inspect the various
+pass lists to determine what passes are available. However, other
+plugins might add new passes. Also, future changes to GCC might cause
+generic passes to be added after plugin loading.
+When a pass is first added to one of the pass lists, the event
+@code{PLUGIN_NEW_PASS} is invoked, with the callback parameter
+@code{gcc_data} pointing to the new pass.
+
+
@section Building GCC plugins
If plugins are enabled, GCC installs the headers needed to build a
diff --git a/gcc/expr.c b/gcc/expr.c
index 75c17923cd0..13ae5fffc9f 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6840,9 +6840,8 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
return expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
case CONST_DECL:
- /* Recurse and make the output_constant_def clause above handle this. */
- return expand_expr_addr_expr_1 (DECL_INITIAL (exp), target,
- tmode, modifier, as);
+ /* Expand the initializer like constants above. */
+ return XEXP (expand_expr_constant (DECL_INITIAL (exp), 0, modifier), 0);
case REALPART_EXPR:
/* The real part of the complex number is always first, therefore
diff --git a/gcc/final.c b/gcc/final.c
index 5d037f53933..0d19562acbf 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -4382,6 +4382,8 @@ rest_of_clean_state (void)
: "");
flag_dump_noaddr = flag_dump_unnumbered = 1;
+ if (flag_compare_debug_opt || flag_compare_debug)
+ dump_flags |= TDF_NOUID;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if (LABEL_P (insn))
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 8b6c4ce6a9c..b39afe173f7 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,85 @@
+2009-12-01 Janne Blomqvist <jb@gcc.gnu.org>
+
+ * PR fortran/42131
+ * trans-stmt.c (gfc_trans_do): Sign test using ternary operator.
+
+2009-11-30 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/42053
+ * resolve.c (resolve_select_type): Check for duplicate CLASS IS blocks.
+
+2009-11-30 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/41631
+ * decl.c (gfc_match_derived_decl): Set extension level.
+ * gfortran.h (symbol_attribute): Expand 'extension' bit field to 8 bit.
+ * iresolve.c (gfc_resolve_extends_type_of): Return value of
+ 'is_extension_of' has kind=4.
+ * match.c (select_type_set_tmp,gfc_match_class_is): Create temporary
+ for CLASS IS blocks.
+ * module.c (MOD_VERSION): Bump module version.
+ (ab_attribute,attr_bits): Remove AB_EXTENSION.
+ (mio_symbol_attribute): Handle expanded 'extension' field.
+ * resolve.c (resolve_select_type): Implement CLASS IS blocks.
+ (resolve_fl_variable_derived): Show correct type name.
+ * symbol.c (gfc_build_class_symbol): Set extension level.
+
+2009-11-30 Janus Weil <janus@gcc.gnu.org>
+
+ * intrinsic.h (gfc_resolve_extends_type_of): Add prototype.
+ * intrinsic.c (add_functions): Use 'gfc_resolve_extends_type_of'.
+ * iresolve.c (gfc_resolve_extends_type_of): New function, which
+ replaces the call to EXTENDS_TYPE_OF by the library function
+ 'is_extension_of' and modifies the arguments.
+ * trans-intrinsic.c (gfc_conv_extends_type_of): Removed.
+ (gfc_conv_intrinsic_function): FOR EXTENDS_TYPE_OF, don't call
+ gfc_conv_extends_type_of but gfc_conv_intrinsic_funcall.
+
+2009-11-30 Paul Thomas <pault@gcc.gnu.org>
+ Janus Weil <janus@gcc.gnu.org>
+
+ * decl.c (encapsulate_class_symbol): Replaced by
+ 'gfc_build_class_symbol'.
+ (build_sym,build_struct): Call 'gfc_build_class_symbol'.
+ (gfc_match_derived_decl): Replace vindex by hash_value.
+ * dump-parse-tree.c (show_symbol): Replace vindex by hash_value.
+ * gfortran.h (symbol_attribute): Add field 'vtab'.
+ (gfc_symbol): Replace vindex by hash_value.
+ (gfc_class_esym_list): Ditto.
+ (gfc_get_derived_type,gfc_build_class_symbol,gfc_find_derived_vtab):
+ New prototypes.
+ * module.c (mio_symbol): Replace vindex by hash_value.
+ * resolve.c (vindex_expr): Rename to 'hash_value_expr'.
+ (resolve_class_compcall,resolve_class_typebound_call): Renamed
+ 'vindex_expr'.
+ (resolve_select_type): Replace $vindex by $vptr->$hash.
+ * symbol.c (gfc_add_save): Handle vtab symbols.
+ (gfc_type_compatible): Rewrite.
+ (gfc_build_class_symbol): New function which replaces
+ 'encapsulate_class_symbol'.
+ (gfc_find_derived_vtab): New function to set up a vtab symbol for a
+ derived type.
+ * trans-decl.c (gfc_create_module_variable): Handle vtab symbols.
+ * trans-expr.c (select_class_proc): Replace vindex by hash_value.
+ (gfc_conv_derived_to_class): New function to construct a temporary
+ CLASS variable from a derived type expression.
+ (gfc_conv_procedure_call): Call 'gfc_conv_derived_to_class'.
+ (gfc_conv_structure): Initialize the $extends and $size fields of
+ vtab symbols.
+ (gfc_trans_class_assign): Replace $vindex by $vptr. Remove the $size
+ assignment.
+ * trans-intrinsic.c (gfc_conv_same_type_as): Replace $vindex by
+ $vptr->$hash, and replace vindex by hash_value.
+ * trans-stmt.c (gfc_trans_allocate): Insert $vptr references, replace
+ $vindex by $vptr. Remove the $size assignment.
+ * trans-types.c (gfc_get_derived_type): Make it non-static.
+
+2009-11-30 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/42131
+ * trans-stmt.c (gfc_trans_do): Calculate loop count
+ without if statements.
+
2009-11-28 Jakub Jelinek <jakub@redhat.com>
* trans-common.c (create_common): Remove unused offset variable.
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 23ac5c39424..90f30b32175 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -1025,88 +1025,6 @@ verify_c_interop_param (gfc_symbol *sym)
}
-/* Build a polymorphic CLASS entity, using the symbol that comes from build_sym.
- A CLASS entity is represented by an encapsulating type, which contains the
- declared type as '$data' component, plus an integer component '$vindex'
- which determines the dynamic type, and another integer '$size', which
- contains the size of the dynamic type structure. */
-
-static gfc_try
-encapsulate_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
- gfc_array_spec **as)
-{
- char name[GFC_MAX_SYMBOL_LEN + 5];
- gfc_symbol *fclass;
- gfc_component *c;
-
- /* Determine the name of the encapsulating type. */
- if ((*as) && (*as)->rank && attr->allocatable)
- sprintf (name, ".class.%s.%d.a", ts->u.derived->name, (*as)->rank);
- else if ((*as) && (*as)->rank)
- sprintf (name, ".class.%s.%d", ts->u.derived->name, (*as)->rank);
- else if (attr->allocatable)
- sprintf (name, ".class.%s.a", ts->u.derived->name);
- else
- sprintf (name, ".class.%s", ts->u.derived->name);
-
- gfc_find_symbol (name, ts->u.derived->ns, 0, &fclass);
- if (fclass == NULL)
- {
- gfc_symtree *st;
- /* If not there, create a new symbol. */
- fclass = gfc_new_symbol (name, ts->u.derived->ns);
- st = gfc_new_symtree (&ts->u.derived->ns->sym_root, name);
- st->n.sym = fclass;
- gfc_set_sym_referenced (fclass);
- fclass->refs++;
- fclass->ts.type = BT_UNKNOWN;
- fclass->vindex = ts->u.derived->vindex;
- fclass->attr.abstract = ts->u.derived->attr.abstract;
- if (ts->u.derived->f2k_derived)
- fclass->f2k_derived = gfc_get_namespace (NULL, 0);
- if (gfc_add_flavor (&fclass->attr, FL_DERIVED,
- NULL, &gfc_current_locus) == FAILURE)
- return FAILURE;
-
- /* Add component '$data'. */
- if (gfc_add_component (fclass, "$data", &c) == FAILURE)
- return FAILURE;
- c->ts = *ts;
- c->ts.type = BT_DERIVED;
- c->attr.access = ACCESS_PRIVATE;
- c->ts.u.derived = ts->u.derived;
- c->attr.pointer = attr->pointer || attr->dummy;
- c->attr.allocatable = attr->allocatable;
- c->attr.dimension = attr->dimension;
- c->attr.abstract = ts->u.derived->attr.abstract;
- c->as = (*as);
- c->initializer = gfc_get_expr ();
- c->initializer->expr_type = EXPR_NULL;
-
- /* Add component '$vindex'. */
- if (gfc_add_component (fclass, "$vindex", &c) == FAILURE)
- return FAILURE;
- c->ts.type = BT_INTEGER;
- c->ts.kind = 4;
- c->attr.access = ACCESS_PRIVATE;
- c->initializer = gfc_int_expr (0);
-
- /* Add component '$size'. */
- if (gfc_add_component (fclass, "$size", &c) == FAILURE)
- return FAILURE;
- c->ts.type = BT_INTEGER;
- c->ts.kind = 4;
- c->attr.access = ACCESS_PRIVATE;
- c->initializer = gfc_int_expr (0);
- }
-
- fclass->attr.extension = 1;
- fclass->attr.is_class = 1;
- ts->u.derived = fclass;
- attr->allocatable = attr->pointer = attr->dimension = 0;
- (*as) = NULL; /* XXX */
- return SUCCESS;
-}
/* Function called by variable_decl() that adds a name to the symbol table. */
@@ -1185,7 +1103,7 @@ build_sym (const char *name, gfc_charlen *cl,
sym->attr.class_ok = (sym->attr.dummy
|| sym->attr.pointer
|| sym->attr.allocatable) ? 1 : 0;
- encapsulate_class_symbol (&sym->ts, &sym->attr, &sym->as);
+ gfc_build_class_symbol (&sym->ts, &sym->attr, &sym->as);
}
return SUCCESS;
@@ -1594,7 +1512,7 @@ build_struct (const char *name, gfc_charlen *cl, gfc_expr **init,
scalar:
if (c->ts.type == BT_CLASS)
- encapsulate_class_symbol (&c->ts, &c->attr, &c->as);
+ gfc_build_class_symbol (&c->ts, &c->attr, &c->as);
return t;
}
@@ -6926,13 +6844,23 @@ gfc_match_derived_decl (void)
/* Add the extended derived type as the first component. */
gfc_add_component (sym, parent, &p);
- sym->attr.extension = attr.extension;
extended->refs++;
gfc_set_sym_referenced (extended);
p->ts.type = BT_DERIVED;
p->ts.u.derived = extended;
p->initializer = gfc_default_initializer (&p->ts);
+
+ /* Set extension level. */
+ if (extended->attr.extension == 255)
+ {
+ /* Since the extension field is 8 bit wide, we can only have
+ up to 255 extension levels. */
+ gfc_error ("Maximum extension level reached with type '%s' at %L",
+ extended->name, &extended->declared_at);
+ return MATCH_ERROR;
+ }
+ sym->attr.extension = extended->attr.extension + 1;
/* Provide the links between the extended type and its extension. */
if (!extended->f2k_derived)
@@ -6941,9 +6869,9 @@ gfc_match_derived_decl (void)
st->n.sym = sym;
}
- if (!sym->vindex)
- /* Set the vindex for this type. */
- sym->vindex = hash_value (sym);
+ if (!sym->hash_value)
+ /* Set the hash for the compound name for this type. */
+ sym->hash_value = hash_value (sym);
/* Take over the ABSTRACT attribute. */
sym->attr.abstract = attr.abstract;
diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
index 32ff298d6e0..97289c26aa5 100644
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -827,8 +827,8 @@ show_symbol (gfc_symbol *sym)
if (sym->f2k_derived)
{
show_indent ();
- if (sym->vindex)
- fprintf (dumpfile, "vindex: %d", sym->vindex);
+ if (sym->hash_value)
+ fprintf (dumpfile, "hash: %d", sym->hash_value);
show_f2k_derived (sym->f2k_derived);
}
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index cc3ccf5527c..e552203cb91 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -670,9 +670,10 @@ typedef struct
unsigned untyped:1; /* No implicit type could be found. */
unsigned is_bind_c:1; /* say if is bound to C. */
- unsigned extension:1; /* extends a derived type. */
+ unsigned extension:8; /* extension level of a derived type. */
unsigned is_class:1; /* is a CLASS container. */
unsigned class_ok:1; /* is a CLASS object with correct attributes. */
+ unsigned vtab:1; /* is a derived type vtab. */
/* These flags are both in the typespec and attribute. The attribute
list is what gets read from/written to a module file. The typespec
@@ -1137,8 +1138,8 @@ typedef struct gfc_symbol
int entry_id; /* Used in resolve.c for entries. */
- /* CLASS vindex for declared and dynamic types in the class. */
- int vindex;
+ /* CLASS hashed name for declared and dynamic types in the class. */
+ int hash_value;
struct gfc_symbol *common_next; /* Links for COMMON syms */
@@ -1599,7 +1600,7 @@ typedef struct gfc_class_esym_list
{
gfc_symbol *derived;
gfc_symbol *esym;
- struct gfc_expr *vindex;
+ struct gfc_expr *hash_value;
struct gfc_class_esym_list *next;
}
gfc_class_esym_list;
@@ -2380,6 +2381,7 @@ gfc_try gfc_check_any_c_kind (gfc_typespec *);
int gfc_validate_kind (bt, int, bool);
int gfc_get_int_kind_from_width_isofortranenv (int size);
int gfc_get_real_kind_from_width_isofortranenv (int size);
+tree gfc_get_derived_type (gfc_symbol * derived);
extern int gfc_index_integer_kind;
extern int gfc_default_integer_kind;
extern int gfc_max_integer_kind;
@@ -2517,6 +2519,9 @@ void gfc_free_dt_list (void);
gfc_gsymbol *gfc_get_gsymbol (const char *);
gfc_gsymbol *gfc_find_gsymbol (gfc_gsymbol *, const char *);
+gfc_try gfc_build_class_symbol (gfc_typespec *, symbol_attribute *,
+ gfc_array_spec **);
+gfc_symbol *gfc_find_derived_vtab (gfc_symbol *);
gfc_typebound_proc* gfc_get_typebound_proc (void);
gfc_symbol* gfc_get_derived_super_type (gfc_symbol*);
gfc_symbol* gfc_get_ultimate_derived_super_type (gfc_symbol*);
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index a62dd92375b..859fd4b7abf 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -1601,7 +1601,7 @@ add_functions (void)
add_sym_2 ("extends_type_of", GFC_ISYM_EXTENDS_TYPE_OF, CLASS_INQUIRY,
ACTUAL_NO, BT_LOGICAL, dl, GFC_STD_F2003,
- gfc_check_same_type_as, NULL, NULL,
+ gfc_check_same_type_as, NULL, gfc_resolve_extends_type_of,
a, BT_UNKNOWN, 0, REQUIRED,
mo, BT_UNKNOWN, 0, REQUIRED);
diff --git a/gcc/fortran/intrinsic.h b/gcc/fortran/intrinsic.h
index acd3f7896d0..cf436db37fd 100644
--- a/gcc/fortran/intrinsic.h
+++ b/gcc/fortran/intrinsic.h
@@ -390,6 +390,7 @@ void gfc_resolve_eoshift (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *,
void gfc_resolve_etime_sub (gfc_code *);
void gfc_resolve_exp (gfc_expr *, gfc_expr *);
void gfc_resolve_exponent (gfc_expr *, gfc_expr *);
+void gfc_resolve_extends_type_of (gfc_expr *, gfc_expr *, gfc_expr *);
void gfc_resolve_fdate (gfc_expr *);
void gfc_resolve_floor (gfc_expr *, gfc_expr *, gfc_expr *);
void gfc_resolve_fnum (gfc_expr *, gfc_expr *);
diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c
index 960be088531..7e8bdfb0cea 100644
--- a/gcc/fortran/iresolve.c
+++ b/gcc/fortran/iresolve.c
@@ -806,6 +806,57 @@ gfc_resolve_exponent (gfc_expr *f, gfc_expr *x)
}
+/* Resolve the EXTENDS_TYPE_OF intrinsic function. */
+
+void
+gfc_resolve_extends_type_of (gfc_expr *f, gfc_expr *a, gfc_expr *mo)
+{
+ gfc_symbol *vtab;
+ gfc_symtree *st;
+
+ /* Prevent double resolution. */
+ if (f->ts.type == BT_LOGICAL)
+ return;
+
+ /* Replace the first argument with the corresponding vtab. */
+ if (a->ts.type == BT_CLASS)
+ gfc_add_component_ref (a, "$vptr");
+ else if (a->ts.type == BT_DERIVED)
+ {
+ vtab = gfc_find_derived_vtab (a->ts.u.derived);
+ /* Clear the old expr. */
+ gfc_free_ref_list (a->ref);
+ memset (a, '\0', sizeof (gfc_expr));
+ /* Construct a new one. */
+ a->expr_type = EXPR_VARIABLE;
+ st = gfc_find_symtree (vtab->ns->sym_root, vtab->name);
+ a->symtree = st;
+ a->ts = vtab->ts;
+ }
+
+ /* Replace the second argument with the corresponding vtab. */
+ if (mo->ts.type == BT_CLASS)
+ gfc_add_component_ref (mo, "$vptr");
+ else if (mo->ts.type == BT_DERIVED)
+ {
+ vtab = gfc_find_derived_vtab (mo->ts.u.derived);
+ /* Clear the old expr. */
+ gfc_free_ref_list (mo->ref);
+ memset (mo, '\0', sizeof (gfc_expr));
+ /* Construct a new one. */
+ mo->expr_type = EXPR_VARIABLE;
+ st = gfc_find_symtree (vtab->ns->sym_root, vtab->name);
+ mo->symtree = st;
+ mo->ts = vtab->ts;
+ }
+
+ f->ts.type = BT_LOGICAL;
+ f->ts.kind = 4;
+ /* Call library function. */
+ f->value.function.name = gfc_get_string (PREFIX ("is_extension_of"));
+}
+
+
void
gfc_resolve_fdate (gfc_expr *f)
{
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 153dfdb3073..9e76818badc 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -3968,13 +3968,25 @@ select_type_set_tmp (gfc_typespec *ts)
{
char name[GFC_MAX_SYMBOL_LEN];
gfc_symtree *tmp;
+
+ if (!gfc_type_is_extensible (ts->u.derived))
+ return;
- sprintf (name, "tmp$%s", ts->u.derived->name);
+ if (ts->type == BT_CLASS)
+ sprintf (name, "tmp$class$%s", ts->u.derived->name);
+ else
+ sprintf (name, "tmp$type$%s", ts->u.derived->name);
gfc_get_sym_tree (name, gfc_current_ns, &tmp, false);
gfc_add_type (tmp->n.sym, ts, NULL);
gfc_set_sym_referenced (tmp->n.sym);
gfc_add_pointer (&tmp->n.sym->attr, NULL);
gfc_add_flavor (&tmp->n.sym->attr, FL_VARIABLE, name, NULL);
+ if (ts->type == BT_CLASS)
+ {
+ gfc_build_class_symbol (&tmp->n.sym->ts, &tmp->n.sym->attr,
+ &tmp->n.sym->as);
+ tmp->n.sym->attr.class_ok = 1;
+ }
select_type_stack->tmp = tmp;
}
@@ -4228,8 +4240,9 @@ gfc_match_class_is (void)
new_st.op = EXEC_SELECT_TYPE;
new_st.ext.case_list = c;
-
- gfc_error_now ("CLASS IS specification at %C is not yet supported");
+
+ /* Create temporary variable. */
+ select_type_set_tmp (&c->ts);
return MATCH_YES;
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index 36095a2b722..d732b66da58 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -77,7 +77,7 @@ along with GCC; see the file COPYING3. If not see
/* Don't put any single quote (') in MOD_VERSION,
if yout want it to be recognized. */
-#define MOD_VERSION "3"
+#define MOD_VERSION "4"
/* Structure that describes a position within a module file. */
@@ -1671,7 +1671,7 @@ typedef enum
AB_CRAY_POINTER, AB_CRAY_POINTEE, AB_THREADPRIVATE, AB_ALLOC_COMP,
AB_POINTER_COMP, AB_PRIVATE_COMP, AB_VALUE, AB_VOLATILE, AB_PROTECTED,
AB_IS_BIND_C, AB_IS_C_INTEROP, AB_IS_ISO_C, AB_ABSTRACT, AB_ZERO_COMP,
- AB_EXTENSION, AB_IS_CLASS, AB_PROCEDURE, AB_PROC_POINTER
+ AB_IS_CLASS, AB_PROCEDURE, AB_PROC_POINTER
}
ab_attribute;
@@ -1711,7 +1711,6 @@ static const mstring attr_bits[] =
minit ("ZERO_COMP", AB_ZERO_COMP),
minit ("PROTECTED", AB_PROTECTED),
minit ("ABSTRACT", AB_ABSTRACT),
- minit ("EXTENSION", AB_EXTENSION),
minit ("IS_CLASS", AB_IS_CLASS),
minit ("PROCEDURE", AB_PROCEDURE),
minit ("PROC_POINTER", AB_PROC_POINTER),
@@ -1771,7 +1770,7 @@ static void
mio_symbol_attribute (symbol_attribute *attr)
{
atom_type t;
- unsigned ext_attr;
+ unsigned ext_attr,extension_level;
mio_lparen ();
@@ -1780,10 +1779,15 @@ mio_symbol_attribute (symbol_attribute *attr)
attr->proc = MIO_NAME (procedure_type) (attr->proc, procedures);
attr->if_source = MIO_NAME (ifsrc) (attr->if_source, ifsrc_types);
attr->save = MIO_NAME (save_state) (attr->save, save_status);
+
ext_attr = attr->ext_attr;
mio_integer ((int *) &ext_attr);
attr->ext_attr = ext_attr;
+ extension_level = attr->extension;
+ mio_integer ((int *) &extension_level);
+ attr->extension = extension_level;
+
if (iomode == IO_OUTPUT)
{
if (attr->allocatable)
@@ -1858,8 +1862,6 @@ mio_symbol_attribute (symbol_attribute *attr)
MIO_NAME (ab_attribute) (AB_PRIVATE_COMP, attr_bits);
if (attr->zero_comp)
MIO_NAME (ab_attribute) (AB_ZERO_COMP, attr_bits);
- if (attr->extension)
- MIO_NAME (ab_attribute) (AB_EXTENSION, attr_bits);
if (attr->is_class)
MIO_NAME (ab_attribute) (AB_IS_CLASS, attr_bits);
if (attr->procedure)
@@ -1984,9 +1986,6 @@ mio_symbol_attribute (symbol_attribute *attr)
case AB_ZERO_COMP:
attr->zero_comp = 1;
break;
- case AB_EXTENSION:
- attr->extension = 1;
- break;
case AB_IS_CLASS:
attr->is_class = 1;
break;
@@ -3574,7 +3573,7 @@ mio_symbol (gfc_symbol *sym)
mio_integer (&(sym->intmod_sym_id));
if (sym->attr.flavor == FL_DERIVED)
- mio_integer (&(sym->vindex));
+ mio_integer (&(sym->hash_value));
mio_rparen ();
}
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index b6853129d59..bf705c6a09a 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -5218,41 +5218,35 @@ resolve_class_esym (gfc_expr *e)
}
-/* Generate an expression for the vindex, given the reference to
+/* Generate an expression for the hash value, given the reference to
the class of the final expression (class_ref), the base of the
full reference list (new_ref), the declared type and the class
object (st). */
static gfc_expr*
-vindex_expr (gfc_ref *class_ref, gfc_ref *new_ref,
- gfc_symbol *declared, gfc_symtree *st)
+hash_value_expr (gfc_ref *class_ref, gfc_ref *new_ref, gfc_symtree *st)
{
- gfc_expr *vindex;
- gfc_ref *ref;
+ gfc_expr *hash_value;
- /* Build an expression for the correct vindex; ie. that of the last
+ /* Build an expression for the correct hash_value; ie. that of the last
CLASS reference. */
- ref = gfc_get_ref();
- ref->type = REF_COMPONENT;
- ref->u.c.component = declared->components->next;
- ref->u.c.sym = declared;
- ref->next = NULL;
if (class_ref)
{
- class_ref->next = ref;
+ class_ref->next = NULL;
}
else
{
gfc_free_ref_list (new_ref);
- new_ref = ref;
+ new_ref = NULL;
}
- vindex = gfc_get_expr ();
- vindex->expr_type = EXPR_VARIABLE;
- vindex->symtree = st;
- vindex->symtree->n.sym->refs++;
- vindex->ts = ref->u.c.component->ts;
- vindex->ref = new_ref;
+ hash_value = gfc_get_expr ();
+ hash_value->expr_type = EXPR_VARIABLE;
+ hash_value->symtree = st;
+ hash_value->symtree->n.sym->refs++;
+ hash_value->ref = new_ref;
+ gfc_add_component_ref (hash_value, "$vptr");
+ gfc_add_component_ref (hash_value, "$hash");
- return vindex;
+ return hash_value;
}
@@ -5352,10 +5346,10 @@ resolve_class_compcall (gfc_expr* e)
resolve_class_esym (e);
/* More than one typebound procedure so transmit an expression for
- the vindex as the selector. */
+ the hash_value as the selector. */
if (e->value.function.class_esym != NULL)
- e->value.function.class_esym->vindex
- = vindex_expr (class_ref, new_ref, declared, st);
+ e->value.function.class_esym->hash_value
+ = hash_value_expr (class_ref, new_ref, st);
return class_try;
}
@@ -5407,10 +5401,10 @@ resolve_class_typebound_call (gfc_code *code)
resolve_class_esym (code->expr1);
/* More than one typebound procedure so transmit an expression for
- the vindex as the selector. */
+ the hash_value as the selector. */
if (code->expr1->value.function.class_esym != NULL)
- code->expr1->value.function.class_esym->vindex
- = vindex_expr (class_ref, new_ref, declared, st);
+ code->expr1->value.function.class_esym->hash_value
+ = hash_value_expr (class_ref, new_ref, st);
return class_try;
}
@@ -6862,11 +6856,13 @@ static void
resolve_select_type (gfc_code *code)
{
gfc_symbol *selector_type;
- gfc_code *body, *new_st;
- gfc_case *c, *default_case;
+ gfc_code *body, *new_st, *if_st, *tail;
+ gfc_code *class_is = NULL, *default_case = NULL;
+ gfc_case *c;
gfc_symtree *st;
char name[GFC_MAX_SYMBOL_LEN];
gfc_namespace *ns;
+ int error = 0;
ns = code->ext.ns;
gfc_resolve (ns);
@@ -6876,9 +6872,6 @@ resolve_select_type (gfc_code *code)
else
selector_type = code->expr1->ts.u.derived->components->ts.u.derived;
- /* Assume there is no DEFAULT case. */
- default_case = NULL;
-
/* Loop over TYPE IS / CLASS IS cases. */
for (body = code->block; body; body = body->block)
{
@@ -6890,6 +6883,7 @@ resolve_select_type (gfc_code *code)
{
gfc_error ("Derived type '%s' at %L must be extensible",
c->ts.u.derived->name, &c->where);
+ error++;
continue;
}
@@ -6899,6 +6893,7 @@ resolve_select_type (gfc_code *code)
{
gfc_error ("Derived type '%s' at %L must be an extension of '%s'",
c->ts.u.derived->name, &c->where, selector_type->name);
+ error++;
continue;
}
@@ -6906,15 +6901,21 @@ resolve_select_type (gfc_code *code)
if (c->ts.type == BT_UNKNOWN)
{
/* Check F03:C818. */
- if (default_case != NULL)
- gfc_error ("The DEFAULT CASE at %L cannot be followed "
- "by a second DEFAULT CASE at %L",
- &default_case->where, &c->where);
+ if (default_case)
+ {
+ gfc_error ("The DEFAULT CASE at %L cannot be followed "
+ "by a second DEFAULT CASE at %L",
+ &default_case->ext.case_list->where, &c->where);
+ error++;
+ continue;
+ }
else
- default_case = c;
- continue;
+ default_case = body;
}
}
+
+ if (error>0)
+ return;
if (code->expr2)
{
@@ -6944,45 +6945,153 @@ resolve_select_type (gfc_code *code)
/* Transform to EXEC_SELECT. */
code->op = EXEC_SELECT;
- gfc_add_component_ref (code->expr1, "$vindex");
+ gfc_add_component_ref (code->expr1, "$vptr");
+ gfc_add_component_ref (code->expr1, "$hash");
/* Loop over TYPE IS / CLASS IS cases. */
for (body = code->block; body; body = body->block)
{
c = body->ext.case_list;
+
if (c->ts.type == BT_DERIVED)
- c->low = c->high = gfc_int_expr (c->ts.u.derived->vindex);
- else if (c->ts.type == BT_CLASS)
- /* Currently IS CLASS blocks are simply ignored.
- TODO: Implement IS CLASS. */
- c->unreachable = 1;
-
- if (c->ts.type != BT_DERIVED)
+ c->low = c->high = gfc_int_expr (c->ts.u.derived->hash_value);
+ else if (c->ts.type == BT_UNKNOWN)
continue;
+
/* Assign temporary to selector. */
- sprintf (name, "tmp$%s", c->ts.u.derived->name);
+ if (c->ts.type == BT_CLASS)
+ sprintf (name, "tmp$class$%s", c->ts.u.derived->name);
+ else
+ sprintf (name, "tmp$type$%s", c->ts.u.derived->name);
st = gfc_find_symtree (ns->sym_root, name);
new_st = gfc_get_code ();
- new_st->op = EXEC_POINTER_ASSIGN;
new_st->expr1 = gfc_get_variable_expr (st);
new_st->expr2 = gfc_get_variable_expr (code->expr1->symtree);
- gfc_add_component_ref (new_st->expr2, "$data");
+ if (c->ts.type == BT_DERIVED)
+ {
+ new_st->op = EXEC_POINTER_ASSIGN;
+ gfc_add_component_ref (new_st->expr2, "$data");
+ }
+ else
+ new_st->op = EXEC_POINTER_ASSIGN;
new_st->next = body->next;
body->next = new_st;
}
+
+ /* Take out CLASS IS cases for separate treatment. */
+ body = code;
+ while (body && body->block)
+ {
+ if (body->block->ext.case_list->ts.type == BT_CLASS)
+ {
+ /* Add to class_is list. */
+ if (class_is == NULL)
+ {
+ class_is = body->block;
+ tail = class_is;
+ }
+ else
+ {
+ for (tail = class_is; tail->block; tail = tail->block) ;
+ tail->block = body->block;
+ tail = tail->block;
+ }
+ /* Remove from EXEC_SELECT list. */
+ body->block = body->block->block;
+ tail->block = NULL;
+ }
+ else
+ body = body->block;
+ }
- /* Eliminate dead blocks. */
- for (body = code; body && body->block; body = body->block)
+ if (class_is)
{
- if (body->block->ext.case_list->unreachable)
+ gfc_symbol *vtab;
+
+ if (!default_case)
+ {
+ /* Add a default case to hold the CLASS IS cases. */
+ for (tail = code; tail->block; tail = tail->block) ;
+ tail->block = gfc_get_code ();
+ tail = tail->block;
+ tail->op = EXEC_SELECT_TYPE;
+ tail->ext.case_list = gfc_get_case ();
+ tail->ext.case_list->ts.type = BT_UNKNOWN;
+ tail->next = NULL;
+ default_case = tail;
+ }
+
+ /* More than one CLASS IS block? */
+ if (class_is->block)
{
- /* Cut the unreachable block from the code chain. */
- gfc_code *cd = body->block;
- body->block = cd->block;
- /* Kill the dead block, but not the blocks below it. */
- cd->block = NULL;
- gfc_free_statements (cd);
+ gfc_code **c1,*c2;
+ bool swapped;
+ /* Sort CLASS IS blocks by extension level. */
+ do
+ {
+ swapped = false;
+ for (c1 = &class_is; (*c1) && (*c1)->block; c1 = &((*c1)->block))
+ {
+ c2 = (*c1)->block;
+ /* F03:C817 (check for doubles). */
+ if ((*c1)->ext.case_list->ts.u.derived->hash_value
+ == c2->ext.case_list->ts.u.derived->hash_value)
+ {
+ gfc_error ("Double CLASS IS block in SELECT TYPE "
+ "statement at %L", &c2->ext.case_list->where);
+ return;
+ }
+ if ((*c1)->ext.case_list->ts.u.derived->attr.extension
+ < c2->ext.case_list->ts.u.derived->attr.extension)
+ {
+ /* Swap. */
+ (*c1)->block = c2->block;
+ c2->block = *c1;
+ *c1 = c2;
+ swapped = true;
+ }
+ }
+ }
+ while (swapped);
}
+
+ /* Generate IF chain. */
+ if_st = gfc_get_code ();
+ if_st->op = EXEC_IF;
+ new_st = if_st;
+ for (body = class_is; body; body = body->block)
+ {
+ new_st->block = gfc_get_code ();
+ new_st = new_st->block;
+ new_st->op = EXEC_IF;
+ /* Set up IF condition: Call _gfortran_is_extension_of. */
+ new_st->expr1 = gfc_get_expr ();
+ new_st->expr1->expr_type = EXPR_FUNCTION;
+ new_st->expr1->ts.type = BT_LOGICAL;
+ new_st->expr1->ts.kind = 4;
+ new_st->expr1->value.function.name = gfc_get_string (PREFIX ("is_extension_of"));
+ new_st->expr1->value.function.isym = XCNEW (gfc_intrinsic_sym);
+ new_st->expr1->value.function.isym->id = GFC_ISYM_EXTENDS_TYPE_OF;
+ /* Set up arguments. */
+ new_st->expr1->value.function.actual = gfc_get_actual_arglist ();
+ new_st->expr1->value.function.actual->expr = gfc_get_variable_expr (code->expr1->symtree);
+ gfc_add_component_ref (new_st->expr1->value.function.actual->expr, "$vptr");
+ vtab = gfc_find_derived_vtab (body->ext.case_list->ts.u.derived);
+ st = gfc_find_symtree (vtab->ns->sym_root, vtab->name);
+ new_st->expr1->value.function.actual->next = gfc_get_actual_arglist ();
+ new_st->expr1->value.function.actual->next->expr = gfc_get_variable_expr (st);
+ new_st->next = body->next;
+ }
+ if (default_case->next)
+ {
+ new_st->block = gfc_get_code ();
+ new_st = new_st->block;
+ new_st->op = EXEC_IF;
+ new_st->next = default_case->next;
+ }
+
+ /* Replace CLASS DEFAULT code by the IF chain. */
+ default_case->next = if_st;
}
resolve_select (code);
@@ -8751,7 +8860,8 @@ resolve_fl_variable_derived (gfc_symbol *sym, int no_init_flag)
if (!gfc_type_is_extensible (sym->ts.u.derived->components->ts.u.derived))
{
gfc_error ("Type '%s' of CLASS variable '%s' at %L is not extensible",
- sym->ts.u.derived->name, sym->name, &sym->declared_at);
+ sym->ts.u.derived->components->ts.u.derived->name,
+ sym->name, &sym->declared_at);
return FAILURE;
}
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index c1b39b0d9f1..6dd0a8afa0f 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -1045,7 +1045,7 @@ gfc_add_save (symbol_attribute *attr, const char *name, locus *where)
return FAILURE;
}
- if (attr->save == SAVE_EXPLICIT)
+ if (attr->save == SAVE_EXPLICIT && !attr->vtab)
{
if (gfc_notify_std (GFC_STD_LEGACY,
"Duplicate SAVE attribute specified at %L",
@@ -4592,22 +4592,228 @@ gfc_type_is_extension_of (gfc_symbol *t1, gfc_symbol *t2)
bool
gfc_type_compatible (gfc_typespec *ts1, gfc_typespec *ts2)
{
- if ((ts1->type == BT_DERIVED || ts1->type == BT_CLASS)
- && (ts2->type == BT_DERIVED || ts2->type == BT_CLASS))
+ gfc_component *cmp1, *cmp2;
+
+ bool is_class1 = (ts1->type == BT_CLASS);
+ bool is_class2 = (ts2->type == BT_CLASS);
+ bool is_derived1 = (ts1->type == BT_DERIVED);
+ bool is_derived2 = (ts2->type == BT_DERIVED);
+
+ if (!is_derived1 && !is_derived2 && !is_class1 && !is_class2)
+ return (ts1->type == ts2->type);
+
+ if (is_derived1 && is_derived2)
+ return gfc_compare_derived_types (ts1->u.derived, ts2->u.derived);
+
+ cmp1 = cmp2 = NULL;
+
+ if (is_class1)
{
- if (ts1->type == BT_CLASS && ts2->type == BT_DERIVED)
- return gfc_type_is_extension_of (ts1->u.derived->components->ts.u.derived,
- ts2->u.derived);
- else if (ts1->type == BT_CLASS && ts2->type == BT_CLASS)
- return gfc_type_is_extension_of (ts1->u.derived->components->ts.u.derived,
- ts2->u.derived->components->ts.u.derived);
- else if (ts2->type != BT_CLASS)
- return gfc_compare_derived_types (ts1->u.derived, ts2->u.derived);
- else
+ cmp1 = gfc_find_component (ts1->u.derived, "$data", true, false);
+ if (cmp1 == NULL)
return 0;
}
+
+ if (is_class2)
+ {
+ cmp2 = gfc_find_component (ts2->u.derived, "$data", true, false);
+ if (cmp2 == NULL)
+ return 0;
+ }
+
+ if (is_class1 && is_derived2)
+ return gfc_type_is_extension_of (cmp1->ts.u.derived, ts2->u.derived);
+
+ else if (is_class1 && is_class2)
+ return gfc_type_is_extension_of (cmp1->ts.u.derived, cmp2->ts.u.derived);
+
else
- return (ts1->type == ts2->type);
+ return 0;
+}
+
+
+/* Build a polymorphic CLASS entity, using the symbol that comes from
+ build_sym. A CLASS entity is represented by an encapsulating type,
+ which contains the declared type as '$data' component, plus a pointer
+ component '$vptr' which determines the dynamic type. */
+
+gfc_try
+gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
+ gfc_array_spec **as)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 5];
+ gfc_symbol *fclass;
+ gfc_symbol *vtab;
+ gfc_component *c;
+
+ /* Determine the name of the encapsulating type. */
+ if ((*as) && (*as)->rank && attr->allocatable)
+ sprintf (name, ".class.%s.%d.a", ts->u.derived->name, (*as)->rank);
+ else if ((*as) && (*as)->rank)
+ sprintf (name, ".class.%s.%d", ts->u.derived->name, (*as)->rank);
+ else if (attr->allocatable)
+ sprintf (name, ".class.%s.a", ts->u.derived->name);
+ else
+ sprintf (name, ".class.%s", ts->u.derived->name);
+
+ gfc_find_symbol (name, ts->u.derived->ns, 0, &fclass);
+ if (fclass == NULL)
+ {
+ gfc_symtree *st;
+ /* If not there, create a new symbol. */
+ fclass = gfc_new_symbol (name, ts->u.derived->ns);
+ st = gfc_new_symtree (&ts->u.derived->ns->sym_root, name);
+ st->n.sym = fclass;
+ gfc_set_sym_referenced (fclass);
+ fclass->refs++;
+ fclass->ts.type = BT_UNKNOWN;
+ fclass->attr.abstract = ts->u.derived->attr.abstract;
+ if (ts->u.derived->f2k_derived)
+ fclass->f2k_derived = gfc_get_namespace (NULL, 0);
+ if (gfc_add_flavor (&fclass->attr, FL_DERIVED,
+ NULL, &gfc_current_locus) == FAILURE)
+ return FAILURE;
+
+ /* Add component '$data'. */
+ if (gfc_add_component (fclass, "$data", &c) == FAILURE)
+ return FAILURE;
+ c->ts = *ts;
+ c->ts.type = BT_DERIVED;
+ c->attr.access = ACCESS_PRIVATE;
+ c->ts.u.derived = ts->u.derived;
+ c->attr.pointer = attr->pointer || attr->dummy;
+ c->attr.allocatable = attr->allocatable;
+ c->attr.dimension = attr->dimension;
+ c->attr.abstract = ts->u.derived->attr.abstract;
+ c->as = (*as);
+ c->initializer = gfc_get_expr ();
+ c->initializer->expr_type = EXPR_NULL;
+
+ /* Add component '$vptr'. */
+ if (gfc_add_component (fclass, "$vptr", &c) == FAILURE)
+ return FAILURE;
+ c->ts.type = BT_DERIVED;
+ vtab = gfc_find_derived_vtab (ts->u.derived);
+ gcc_assert (vtab);
+ c->ts.u.derived = vtab->ts.u.derived;
+ c->attr.pointer = 1;
+ c->initializer = gfc_get_expr ();
+ c->initializer->expr_type = EXPR_NULL;
+ }
+
+ /* Since the extension field is 8 bit wide, we can only have
+ up to 255 extension levels. */
+ if (ts->u.derived->attr.extension == 255)
+ {
+ gfc_error ("Maximum extension level reached with type '%s' at %L",
+ ts->u.derived->name, &ts->u.derived->declared_at);
+ return FAILURE;
+ }
+
+ fclass->attr.extension = ts->u.derived->attr.extension + 1;
+ fclass->attr.is_class = 1;
+ ts->u.derived = fclass;
+ attr->allocatable = attr->pointer = attr->dimension = 0;
+ (*as) = NULL; /* XXX */
+ return SUCCESS;
+}
+
+
+/* Find the symbol for a derived type's vtab. */
+
+gfc_symbol *
+gfc_find_derived_vtab (gfc_symbol *derived)
+{
+ gfc_namespace *ns;
+ gfc_symbol *vtab = NULL, *vtype = NULL;
+ char name[2 * GFC_MAX_SYMBOL_LEN + 8];
+
+ ns = gfc_current_ns;
+
+ for (; ns; ns = ns->parent)
+ if (!ns->parent)
+ break;
+
+ if (ns)
+ {
+ sprintf (name, "vtab$%s", derived->name);
+ gfc_find_symbol (name, ns, 0, &vtab);
+
+ if (vtab == NULL)
+ {
+ gfc_get_symbol (name, ns, &vtab);
+ vtab->ts.type = BT_DERIVED;
+ vtab->attr.flavor = FL_VARIABLE;
+ vtab->attr.target = 1;
+ vtab->attr.save = SAVE_EXPLICIT;
+ vtab->attr.vtab = 1;
+ vtab->refs++;
+ gfc_set_sym_referenced (vtab);
+ sprintf (name, "vtype$%s", derived->name);
+
+ gfc_find_symbol (name, ns, 0, &vtype);
+ if (vtype == NULL)
+ {
+ gfc_component *c;
+ gfc_symbol *parent = NULL, *parent_vtab = NULL;
+
+ gfc_get_symbol (name, ns, &vtype);
+ if (gfc_add_flavor (&vtype->attr, FL_DERIVED,
+ NULL, &gfc_current_locus) == FAILURE)
+ return NULL;
+ vtype->refs++;
+ gfc_set_sym_referenced (vtype);
+
+ /* Add component '$hash'. */
+ if (gfc_add_component (vtype, "$hash", &c) == FAILURE)
+ return NULL;
+ c->ts.type = BT_INTEGER;
+ c->ts.kind = 4;
+ c->attr.access = ACCESS_PRIVATE;
+ c->initializer = gfc_int_expr (derived->hash_value);
+
+ /* Add component '$size'. */
+ if (gfc_add_component (vtype, "$size", &c) == FAILURE)
+ return NULL;
+ c->ts.type = BT_INTEGER;
+ c->ts.kind = 4;
+ c->attr.access = ACCESS_PRIVATE;
+ /* Remember the derived type in ts.u.derived,
+ so that the correct initializer can be set later on
+ (in gfc_conv_structure). */
+ c->ts.u.derived = derived;
+ c->initializer = gfc_int_expr (0);
+
+ /* Add component $extends. */
+ if (gfc_add_component (vtype, "$extends", &c) == FAILURE)
+ return NULL;
+ c->attr.pointer = 1;
+ c->attr.access = ACCESS_PRIVATE;
+ c->initializer = gfc_get_expr ();
+ parent = gfc_get_derived_super_type (derived);
+ if (parent)
+ {
+ parent_vtab = gfc_find_derived_vtab (parent);
+ c->ts.type = BT_DERIVED;
+ c->ts.u.derived = parent_vtab->ts.u.derived;
+ c->initializer->expr_type = EXPR_VARIABLE;
+ gfc_find_sym_tree (parent_vtab->name, parent_vtab->ns, 0,
+ &c->initializer->symtree);
+ }
+ else
+ {
+ c->ts.type = BT_DERIVED;
+ c->ts.u.derived = vtype;
+ c->initializer->expr_type = EXPR_NULL;
+ }
+ }
+ vtab->ts.u.derived = vtype;
+
+ vtab->value = gfc_default_initializer (&vtab->ts);
+ }
+ }
+
+ return vtab;
}
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 200c3f5654c..2e3fedd0ed3 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -3405,7 +3405,7 @@ gfc_create_module_variable (gfc_symbol * sym)
&& (sym->equiv_built || sym->attr.in_equivalence))
return;
- if (sym->backend_decl)
+ if (sym->backend_decl && !sym->attr.vtab)
internal_error ("backend decl for module variable %s already exists",
sym->name);
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 77de6bd5773..acca306a2ff 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -1530,16 +1530,16 @@ select_class_proc (gfc_se *se, gfc_class_esym_list *elist,
tree end_label;
tree label;
tree tmp;
- tree vindex;
+ tree hash;
stmtblock_t body;
gfc_class_esym_list *next_elist, *tmp_elist;
gfc_se tmpse;
- /* Convert the vindex expression. */
+ /* Convert the hash expression. */
gfc_init_se (&tmpse, NULL);
- gfc_conv_expr (&tmpse, elist->vindex);
+ gfc_conv_expr (&tmpse, elist->hash_value);
gfc_add_block_to_block (&se->pre, &tmpse.pre);
- vindex = gfc_evaluate_now (tmpse.expr, &se->pre);
+ hash = gfc_evaluate_now (tmpse.expr, &se->pre);
gfc_add_block_to_block (&se->post, &tmpse.post);
/* Fix the function type to be that of the declared type method. */
@@ -1566,9 +1566,9 @@ select_class_proc (gfc_se *se, gfc_class_esym_list *elist,
if (elist->esym != tmp_elist->esym)
continue;
- cval = build_int_cst (TREE_TYPE (vindex),
- elist->derived->vindex);
- /* Build a label for the vindex value. */
+ cval = build_int_cst (TREE_TYPE (hash),
+ elist->derived->hash_value);
+ /* Build a label for the hash value. */
label = gfc_build_label_decl (NULL_TREE);
tmp = fold_build3 (CASE_LABEL_EXPR, void_type_node,
cval, NULL_TREE, label);
@@ -1601,8 +1601,8 @@ select_class_proc (gfc_se *se, gfc_class_esym_list *elist,
segfaults because it occurs too early and too often. */
free_elist:
next_elist = elist->next;
- if (elist->vindex)
- gfc_free_expr (elist->vindex);
+ if (elist->hash_value)
+ gfc_free_expr (elist->hash_value);
gfc_free (elist);
elist = NULL;
}
@@ -1613,12 +1613,12 @@ select_class_proc (gfc_se *se, gfc_class_esym_list *elist,
NULL_TREE, NULL_TREE, label);
gfc_add_expr_to_block (&body, tmp);
tmp = gfc_trans_runtime_error (true, &expr->where,
- "internal error: bad vindex in dynamic dispatch");
+ "internal error: bad hash value in dynamic dispatch");
gfc_add_expr_to_block (&body, tmp);
/* Write the switch expression. */
tmp = gfc_finish_block (&body);
- tmp = build3_v (SWITCH_EXPR, vindex, tmp, NULL_TREE);
+ tmp = build3_v (SWITCH_EXPR, hash, tmp, NULL_TREE);
gfc_add_expr_to_block (&se->pre, tmp);
tmp = build1_v (LABEL_EXPR, end_label);
@@ -2531,6 +2531,60 @@ conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
}
+/* Takes a derived type expression and returns the address of a temporary
+ class object of the 'declared' type. */
+static void
+gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
+ gfc_typespec class_ts)
+{
+ gfc_component *cmp;
+ gfc_symbol *vtab;
+ gfc_symbol *declared = class_ts.u.derived;
+ gfc_ss *ss;
+ tree ctree;
+ tree var;
+ tree tmp;
+
+ /* The derived type needs to be converted to a temporary
+ CLASS object. */
+ tmp = gfc_typenode_for_spec (&class_ts);
+ var = gfc_create_var (tmp, "class");
+
+ /* Set the vptr. */
+ cmp = gfc_find_component (declared, "$vptr", true, true);
+ ctree = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl),
+ var, cmp->backend_decl, NULL_TREE);
+
+ /* Remember the vtab corresponds to the derived type
+ not to the class declared type. */
+ vtab = gfc_find_derived_vtab (e->ts.u.derived);
+ gcc_assert (vtab);
+ tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
+ gfc_add_modify (&parmse->pre, ctree,
+ fold_convert (TREE_TYPE (ctree), tmp));
+
+ /* Now set the data field. */
+ cmp = gfc_find_component (declared, "$data", true, true);
+ ctree = fold_build3 (COMPONENT_REF, TREE_TYPE (cmp->backend_decl),
+ var, cmp->backend_decl, NULL_TREE);
+ ss = gfc_walk_expr (e);
+ if (ss == gfc_ss_terminator)
+ {
+ gfc_conv_expr_reference (parmse, e);
+ tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
+ gfc_add_modify (&parmse->pre, ctree, tmp);
+ }
+ else
+ {
+ gfc_conv_expr (parmse, e);
+ gfc_add_modify (&parmse->pre, ctree, parmse->expr);
+ }
+
+ /* Pass the address of the class object. */
+ parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
+}
+
+
/* The following routine generates code for the intrinsic
procedures from the ISO_C_BINDING module:
* C_LOC (function)
@@ -2800,53 +2854,10 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
else if (fsym && fsym->ts.type == BT_CLASS
&& e->ts.type == BT_DERIVED)
{
- tree data;
- tree vindex;
- tree size;
-
/* The derived type needs to be converted to a temporary
CLASS object. */
gfc_init_se (&parmse, se);
- type = gfc_typenode_for_spec (&fsym->ts);
- var = gfc_create_var (type, "class");
-
- /* Get the components. */
- tmp = fsym->ts.u.derived->components->backend_decl;
- data = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
- var, tmp, NULL_TREE);
- tmp = fsym->ts.u.derived->components->next->backend_decl;
- vindex = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
- var, tmp, NULL_TREE);
- tmp = fsym->ts.u.derived->components->next->next->backend_decl;
- size = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
- var, tmp, NULL_TREE);
-
- /* Set the vindex. */
- tmp = build_int_cst (TREE_TYPE (vindex), e->ts.u.derived->vindex);
- gfc_add_modify (&parmse.pre, vindex, tmp);
-
- /* Set the size. */
- tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&e->ts));
- gfc_add_modify (&parmse.pre, size,
- fold_convert (TREE_TYPE (size), tmp));
-
- /* Now set the data field. */
- argss = gfc_walk_expr (e);
- if (argss == gfc_ss_terminator)
- {
- gfc_conv_expr_reference (&parmse, e);
- tmp = fold_convert (TREE_TYPE (data),
- parmse.expr);
- gfc_add_modify (&parmse.pre, data, tmp);
- }
- else
- {
- gfc_conv_expr (&parmse, e);
- gfc_add_modify (&parmse.pre, data, parmse.expr);
- }
-
- /* Pass the address of the class object. */
- parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
+ gfc_conv_derived_to_class (&parmse, e, fsym->ts);
}
else if (se->ss && se->ss->useflags)
{
@@ -4240,14 +4251,27 @@ gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
if (cm->ts.type == BT_CLASS)
{
+ gfc_component *data;
+ data = gfc_find_component (cm->ts.u.derived, "$data", true, true);
val = gfc_conv_initializer (c->expr, &cm->ts,
- TREE_TYPE (cm->ts.u.derived->components->backend_decl),
- cm->ts.u.derived->components->attr.dimension,
- cm->ts.u.derived->components->attr.pointer);
+ TREE_TYPE (data->backend_decl),
+ data->attr.dimension,
+ data->attr.pointer);
- /* Append it to the constructor list. */
- CONSTRUCTOR_APPEND_ELT (v, cm->ts.u.derived->components->backend_decl,
- val);
+ CONSTRUCTOR_APPEND_ELT (v, data->backend_decl, val);
+ }
+ else if (strcmp (cm->name, "$size") == 0)
+ {
+ val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
+ CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
+ }
+ else if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
+ && strcmp (cm->name, "$extends") == 0)
+ {
+ gfc_symbol *vtabs;
+ vtabs = cm->initializer->symtree->n.sym;
+ val = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
+ CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
}
else
{
@@ -5366,47 +5390,37 @@ gfc_trans_class_assign (gfc_code *code)
{
stmtblock_t block;
tree tmp;
+ gfc_expr *lhs;
+ gfc_expr *rhs;
gfc_start_block (&block);
if (code->expr2->ts.type != BT_CLASS)
{
- /* Insert an additional assignment which sets the '$vindex' field. */
- gfc_expr *lhs,*rhs;
+ /* Insert an additional assignment which sets the '$vptr' field. */
lhs = gfc_copy_expr (code->expr1);
- gfc_add_component_ref (lhs, "$vindex");
- if (code->expr2->ts.type == BT_DERIVED)
- /* vindex is constant, determined at compile time. */
- rhs = gfc_int_expr (code->expr2->ts.u.derived->vindex);
- else if (code->expr2->expr_type == EXPR_NULL)
- rhs = gfc_int_expr (0);
- else
- gcc_unreachable ();
- tmp = gfc_trans_assignment (lhs, rhs, false);
- gfc_add_expr_to_block (&block, tmp);
-
- /* Insert another assignment which sets the '$size' field. */
- lhs = gfc_copy_expr (code->expr1);
- gfc_add_component_ref (lhs, "$size");
+ gfc_add_component_ref (lhs, "$vptr");
if (code->expr2->ts.type == BT_DERIVED)
{
- /* Size is fixed at compile time. */
- gfc_se lse;
- gfc_init_se (&lse, NULL);
- gfc_conv_expr (&lse, lhs);
- tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->expr2->ts));
- gfc_add_modify (&block, lse.expr,
- fold_convert (TREE_TYPE (lse.expr), tmp));
+ gfc_symbol *vtab;
+ gfc_symtree *st;
+ vtab = gfc_find_derived_vtab (code->expr2->ts.u.derived);
+ gcc_assert (vtab);
+
+ rhs = gfc_get_expr ();
+ rhs->expr_type = EXPR_VARIABLE;
+ gfc_find_sym_tree (vtab->name, NULL, 1, &st);
+ rhs->symtree = st;
+ rhs->ts = vtab->ts;
}
else if (code->expr2->expr_type == EXPR_NULL)
- {
- rhs = gfc_int_expr (0);
- tmp = gfc_trans_assignment (lhs, rhs, false);
- gfc_add_expr_to_block (&block, tmp);
- }
+ rhs = gfc_int_expr (0);
else
gcc_unreachable ();
+ tmp = gfc_trans_pointer_assignment (lhs, rhs);
+ gfc_add_expr_to_block (&block, tmp);
+
gfc_free_expr (lhs);
gfc_free_expr (rhs);
}
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 4273b8226e8..208a3b5a8d7 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -4715,14 +4715,20 @@ gfc_conv_same_type_as (gfc_se *se, gfc_expr *expr)
b = expr->value.function.actual->next->expr;
if (a->ts.type == BT_CLASS)
- gfc_add_component_ref (a, "$vindex");
+ {
+ gfc_add_component_ref (a, "$vptr");
+ gfc_add_component_ref (a, "$hash");
+ }
else if (a->ts.type == BT_DERIVED)
- a = gfc_int_expr (a->ts.u.derived->vindex);
+ a = gfc_int_expr (a->ts.u.derived->hash_value);
if (b->ts.type == BT_CLASS)
- gfc_add_component_ref (b, "$vindex");
+ {
+ gfc_add_component_ref (b, "$vptr");
+ gfc_add_component_ref (b, "$hash");
+ }
else if (b->ts.type == BT_DERIVED)
- b = gfc_int_expr (b->ts.u.derived->vindex);
+ b = gfc_int_expr (b->ts.u.derived->hash_value);
gfc_conv_expr (&se1, a);
gfc_conv_expr (&se2, b);
@@ -4733,21 +4739,6 @@ gfc_conv_same_type_as (gfc_se *se, gfc_expr *expr)
}
-/* Generate code for the EXTENDS_TYPE_OF intrinsic. */
-
-static void
-gfc_conv_extends_type_of (gfc_se *se, gfc_expr *expr)
-{
- gfc_expr *e;
- /* TODO: Implement EXTENDS_TYPE_OF. */
- gfc_error ("Intrinsic EXTENDS_TYPE_OF at %L not yet implemented",
- &expr->where);
- /* Just return 'false' for now. */
- e = gfc_logical_expr (false, &expr->where);
- gfc_conv_expr (se, e);
-}
-
-
/* Generate code for SELECTED_CHAR_KIND (NAME) intrinsic function. */
static void
@@ -5157,10 +5148,6 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
gfc_conv_same_type_as (se, expr);
break;
- case GFC_ISYM_EXTENDS_TYPE_OF:
- gfc_conv_extends_type_of (se, expr);
- break;
-
case GFC_ISYM_ABS:
gfc_conv_intrinsic_abs (se, expr);
break;
@@ -5538,6 +5525,7 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
case GFC_ISYM_CHMOD:
case GFC_ISYM_DTIME:
case GFC_ISYM_ETIME:
+ case GFC_ISYM_EXTENDS_TYPE_OF:
case GFC_ISYM_FGET:
case GFC_ISYM_FGETC:
case GFC_ISYM_FNUM:
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 9b2a6230853..32c6efc0c3c 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -1009,44 +1009,57 @@ gfc_trans_do (gfc_code * code)
/* Initialize loop count and jump to exit label if the loop is empty.
This code is executed before we enter the loop body. We generate:
+ step_sign = sign(1,step);
if (step > 0)
{
- if (to < from) goto exit_label;
- countm1 = (to - from) / step;
+ if (to < from)
+ goto exit_label;
}
else
{
- if (to > from) goto exit_label;
- countm1 = (from - to) / -step;
- } */
+ if (to > from)
+ goto exit_label;
+ }
+ countm1 = (to*step_sign - from*step_sign) / (step*step_sign);
+
+ */
+
if (TREE_CODE (type) == INTEGER_TYPE)
{
- tree pos, neg;
+ tree pos, neg, step_sign, to2, from2, step2;
+
+ /* Calculate SIGN (1,step), as (step < 0 ? -1 : 1) */
+
+ tmp = fold_build2 (LT_EXPR, boolean_type_node, step,
+ build_int_cst (TREE_TYPE (step), 0));
+ step_sign = fold_build3 (COND_EXPR, type, tmp,
+ build_int_cst (type, -1),
+ build_int_cst (type, 1));
tmp = fold_build2 (LT_EXPR, boolean_type_node, to, from);
pos = fold_build3 (COND_EXPR, void_type_node, tmp,
build1_v (GOTO_EXPR, exit_label),
build_empty_stmt (input_location));
- tmp = fold_build2 (MINUS_EXPR, type, to, from);
- tmp = fold_convert (utype, tmp);
- tmp = fold_build2 (TRUNC_DIV_EXPR, utype, tmp,
- fold_convert (utype, step));
- tmp = fold_build2 (MODIFY_EXPR, void_type_node, countm1, tmp);
- pos = fold_build2 (COMPOUND_EXPR, void_type_node, pos, tmp);
tmp = fold_build2 (GT_EXPR, boolean_type_node, to, from);
neg = fold_build3 (COND_EXPR, void_type_node, tmp,
build1_v (GOTO_EXPR, exit_label),
build_empty_stmt (input_location));
- tmp = fold_build2 (MINUS_EXPR, type, from, to);
+ tmp = fold_build3 (COND_EXPR, void_type_node, pos_step, pos, neg);
+
+ gfc_add_expr_to_block (&block, tmp);
+
+ /* Calculate the loop count. to-from can overflow, so
+ we cast to unsigned. */
+
+ to2 = fold_build2 (MULT_EXPR, type, step_sign, to);
+ from2 = fold_build2 (MULT_EXPR, type, step_sign, from);
+ step2 = fold_build2 (MULT_EXPR, type, step_sign, step);
+ step2 = fold_convert (utype, step2);
+ tmp = fold_build2 (MINUS_EXPR, type, to2, from2);
tmp = fold_convert (utype, tmp);
- tmp = fold_build2 (TRUNC_DIV_EXPR, utype, tmp,
- fold_convert (utype, fold_build1 (NEGATE_EXPR,
- type, step)));
+ tmp = fold_build2 (TRUNC_DIV_EXPR, utype, tmp, step2);
tmp = fold_build2 (MODIFY_EXPR, void_type_node, countm1, tmp);
- neg = fold_build2 (COMPOUND_EXPR, void_type_node, neg, tmp);
-
- tmp = fold_build3 (COND_EXPR, void_type_node, pos_step, pos, neg);
gfc_add_expr_to_block (&block, tmp);
}
else
@@ -4029,6 +4042,7 @@ gfc_trans_allocate (gfc_code * code)
gfc_expr *sz;
gfc_se se_sz;
sz = gfc_copy_expr (code->expr3);
+ gfc_add_component_ref (sz, "$vptr");
gfc_add_component_ref (sz, "$size");
gfc_init_se (&se_sz, NULL);
gfc_conv_expr (&se_sz, sz);
@@ -4124,42 +4138,49 @@ gfc_trans_allocate (gfc_code * code)
{
gfc_expr *lhs,*rhs;
gfc_se lse;
- /* Initialize VINDEX for CLASS objects. */
+
+ /* Initialize VPTR for CLASS objects. */
lhs = gfc_expr_to_initialize (expr);
- gfc_add_component_ref (lhs, "$vindex");
+ gfc_add_component_ref (lhs, "$vptr");
+ rhs = NULL;
if (code->expr3 && code->expr3->ts.type == BT_CLASS)
{
- /* vindex must be determined at run time. */
+ /* VPTR must be determined at run time. */
rhs = gfc_copy_expr (code->expr3);
- gfc_add_component_ref (rhs, "$vindex");
+ gfc_add_component_ref (rhs, "$vptr");
+ tmp = gfc_trans_pointer_assignment (lhs, rhs);
+ gfc_add_expr_to_block (&block, tmp);
+ gfc_free_expr (rhs);
}
else
{
- /* vindex is fixed at compile time. */
- int vindex;
+ /* VPTR is fixed at compile time. */
+ gfc_symbol *vtab;
+ gfc_typespec *ts;
if (code->expr3)
- vindex = code->expr3->ts.u.derived->vindex;
+ ts = &code->expr3->ts;
+ else if (expr->ts.type == BT_DERIVED)
+ ts = &expr->ts;
else if (code->ext.alloc.ts.type == BT_DERIVED)
- vindex = code->ext.alloc.ts.u.derived->vindex;
+ ts = &code->ext.alloc.ts;
else if (expr->ts.type == BT_CLASS)
- vindex = expr->ts.u.derived->components->ts.u.derived->vindex;
+ ts = &expr->ts.u.derived->components->ts;
else
- vindex = expr->ts.u.derived->vindex;
- rhs = gfc_int_expr (vindex);
- }
- tmp = gfc_trans_assignment (lhs, rhs, false);
- gfc_free_expr (lhs);
- gfc_free_expr (rhs);
- gfc_add_expr_to_block (&block, tmp);
+ ts = &expr->ts;
- /* Initialize SIZE for CLASS objects. */
- lhs = gfc_expr_to_initialize (expr);
- gfc_add_component_ref (lhs, "$size");
- gfc_init_se (&lse, NULL);
- gfc_conv_expr (&lse, lhs);
- gfc_add_modify (&block, lse.expr,
- fold_convert (TREE_TYPE (lse.expr), memsz));
- gfc_free_expr (lhs);
+ if (ts->type == BT_DERIVED)
+ {
+ vtab = gfc_find_derived_vtab (ts->u.derived);
+ gcc_assert (vtab);
+ gfc_init_se (&lse, NULL);
+ lse.want_pointer = 1;
+ gfc_conv_expr (&lse, lhs);
+ tmp = gfc_build_addr_expr (NULL_TREE,
+ gfc_get_symbol_decl (vtab));
+ gfc_add_modify (&block, lse.expr,
+ fold_convert (TREE_TYPE (lse.expr), tmp));
+ }
+ }
}
}
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index 18644779fc1..278ae27a458 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -53,8 +53,6 @@ along with GCC; see the file COPYING3. If not see
/* array of structs so we don't have to worry about xmalloc or free */
CInteropKind_t c_interop_kinds_table[ISOCBINDING_NUMBER];
-static tree gfc_get_derived_type (gfc_symbol * derived);
-
tree gfc_array_index_type;
tree gfc_array_range_type;
tree gfc_character1_type_node;
@@ -1941,7 +1939,7 @@ gfc_get_ppc_type (gfc_component* c)
at the same time. If an equal derived type has been built
in a parent namespace, this is used. */
-static tree
+tree
gfc_get_derived_type (gfc_symbol * derived)
{
tree typenode = NULL, field = NULL, field_type = NULL, fieldlist = NULL;
diff --git a/gcc/function.c b/gcc/function.c
index 88e036c0857..b8042d08551 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -1598,7 +1598,13 @@ instantiate_virtual_regs_in_insn (rtx insn)
if (!safe_insn_predicate (insn_code, i, x))
{
start_sequence ();
- x = force_reg (insn_data[insn_code].operand[i].mode, x);
+ if (REG_P (x))
+ {
+ gcc_assert (REGNO (x) <= LAST_VIRTUAL_REGISTER);
+ x = copy_to_reg (x);
+ }
+ else
+ x = force_reg (insn_data[insn_code].operand[i].mode, x);
seq = get_insns ();
end_sequence ();
if (seq)
diff --git a/gcc/gcc-plugin.h b/gcc/gcc-plugin.h
index 2e36f486262..ec12265417d 100644
--- a/gcc/gcc-plugin.h
+++ b/gcc/gcc-plugin.h
@@ -26,29 +26,19 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
+#include "highlev-plugin-common.h"
+#include "hashtab.h"
-/* Event names. Keep in sync with plugin_event_name[]. */
+/* Event names. */
enum plugin_event
{
- PLUGIN_PASS_MANAGER_SETUP, /* To hook into pass manager. */
- PLUGIN_FINISH_TYPE, /* After finishing parsing a type. */
- PLUGIN_FINISH_UNIT, /* Useful for summary processing. */
- PLUGIN_CXX_CP_PRE_GENERICIZE, /* Allows to see low level AST in C++ FE. */
- PLUGIN_FINISH, /* Called before GCC exits. */
- PLUGIN_INFO, /* Information about the plugin. */
- PLUGIN_GGC_START, /* Called at start of GCC Garbage Collection. */
- PLUGIN_GGC_MARKING, /* Extend the GGC marking. */
- PLUGIN_GGC_END, /* Called at end of GGC. */
- PLUGIN_REGISTER_GGC_ROOTS, /* Register an extra GGC root table. */
- PLUGIN_REGISTER_GGC_CACHES, /* Register an extra GGC cache table. */
- PLUGIN_ATTRIBUTES, /* Called during attribute registration. */
- PLUGIN_START_UNIT, /* Called before processing a translation unit. */
- PLUGIN_PRAGMAS, /* Called during pragma registration. */
- PLUGIN_EVENT_LAST /* Dummy event used for indexing callback
- array. */
+# define DEFEVENT(NAME) NAME,
+# include "plugin.def"
+# undef DEFEVENT
+ PLUGIN_EVENT_FIRST_DYNAMIC
};
-extern const char *plugin_event_name[];
+extern const char **plugin_event_name;
struct plugin_argument
{
@@ -127,14 +117,22 @@ typedef void (*plugin_callback_func) (void *gcc_data, void *user_data);
USER_DATA - plugin-provided data.
*/
+/* Number of event ids / names registered so far. */
+
+extern int get_event_last (void);
+
+int get_named_event_id (const char *name, enum insert_option insert);
+
/* This is also called without a callback routine for the
PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS and
PLUGIN_REGISTER_GGC_CACHES pseudo-events, with a specific user_data.
*/
extern void register_callback (const char *plugin_name,
- enum plugin_event event,
+ int event,
plugin_callback_func callback,
void *user_data);
+extern int unregister_callback (const char *plugin_name, int event);
+
#endif /* GCC_PLUGIN_H */
diff --git a/gcc/graphite-clast-to-gimple.c b/gcc/graphite-clast-to-gimple.c
index 3f3bb3bb434..93138b6bd89 100644
--- a/gcc/graphite-clast-to-gimple.c
+++ b/gcc/graphite-clast-to-gimple.c
@@ -66,6 +66,106 @@ graphite_verify (void)
#endif
}
+/* Stores the INDEX in a vector for a given clast NAME. */
+
+typedef struct clast_name_index {
+ int index;
+ const char *name;
+} *clast_name_index_p;
+
+/* Returns a pointer to a new element of type clast_name_index_p built
+ from NAME and INDEX. */
+
+static inline clast_name_index_p
+new_clast_name_index (const char *name, int index)
+{
+ clast_name_index_p res = XNEW (struct clast_name_index);
+
+ res->name = name;
+ res->index = index;
+ return res;
+}
+
+/* For a given clast NAME, returns -1 if it does not correspond to any
+ parameter, or otherwise, returns the index in the PARAMS or
+ SCATTERING_DIMENSIONS vector. */
+
+static inline int
+clast_name_to_index (const char *name, htab_t index_table)
+{
+ struct clast_name_index tmp;
+ PTR *slot;
+
+ tmp.name = name;
+ slot = htab_find_slot (index_table, &tmp, NO_INSERT);
+
+ if (slot && *slot)
+ return ((struct clast_name_index *) *slot)->index;
+
+ return -1;
+}
+
+/* Records in INDEX_TABLE the INDEX for NAME. */
+
+static inline void
+save_clast_name_index (htab_t index_table, const char *name, int index)
+{
+ struct clast_name_index tmp;
+ PTR *slot;
+
+ tmp.name = name;
+ slot = htab_find_slot (index_table, &tmp, INSERT);
+
+ if (slot)
+ *slot = new_clast_name_index (name, index);
+}
+
+/* Print to stderr the element ELT. */
+
+static inline void
+debug_clast_name_index (clast_name_index_p elt)
+{
+ fprintf (stderr, "(index = %d, name = %s)\n", elt->index, elt->name);
+}
+
+/* Helper function for debug_rename_map. */
+
+static inline int
+debug_clast_name_indexes_1 (void **slot, void *s ATTRIBUTE_UNUSED)
+{
+ struct clast_name_index *entry = (struct clast_name_index *) *slot;
+ debug_clast_name_index (entry);
+ return 1;
+}
+
+/* Print to stderr all the elements of MAP. */
+
+void
+debug_clast_name_indexes (htab_t map)
+{
+ htab_traverse (map, debug_clast_name_indexes_1, NULL);
+}
+
+/* Computes a hash function for database element ELT. */
+
+static inline hashval_t
+clast_name_index_elt_info (const void *elt)
+{
+ return htab_hash_pointer (((const struct clast_name_index *) elt)->name);
+}
+
+/* Compares database elements E1 and E2. */
+
+static inline int
+eq_clast_name_indexes (const void *e1, const void *e2)
+{
+ const struct clast_name_index *elt1 = (const struct clast_name_index *) e1;
+ const struct clast_name_index *elt2 = (const struct clast_name_index *) e2;
+
+ return (elt1->name == elt2->name);
+}
+
+
/* For a given loop DEPTH in the loop nest of the original black box
PBB, return the old induction variable associated to that loop. */
@@ -95,11 +195,10 @@ newivs_to_depth_to_newiv (VEC (tree, heap) *newivs, int depth)
static tree
clast_name_to_gcc (const char *name, sese region, VEC (tree, heap) *newivs,
- htab_t newivs_index)
+ htab_t newivs_index, htab_t params_index)
{
int index;
VEC (tree, heap) *params = SESE_PARAMS (region);
- htab_t params_index = SESE_PARAMS_INDEX (region);
if (params && params_index)
{
@@ -128,7 +227,7 @@ max_precision_type (tree e1, tree e2)
static tree
clast_to_gcc_expression (tree, struct clast_expr *, sese, VEC (tree, heap) *,
- htab_t);
+ htab_t, htab_t);
/* Converts a Cloog reduction expression R with reduction operation OP
to a GCC expression tree of type TYPE. */
@@ -137,17 +236,17 @@ static tree
clast_to_gcc_expression_red (tree type, enum tree_code op,
struct clast_reduction *r,
sese region, VEC (tree, heap) *newivs,
- htab_t newivs_index)
+ htab_t newivs_index, htab_t params_index)
{
int i;
tree res = clast_to_gcc_expression (type, r->elts[0], region, newivs,
- newivs_index);
+ newivs_index, params_index);
tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type;
for (i = 1; i < r->n; i++)
{
tree t = clast_to_gcc_expression (operand_type, r->elts[i], region,
- newivs, newivs_index);
+ newivs, newivs_index, params_index);
res = fold_build2 (op, type, res, t);
}
@@ -160,7 +259,7 @@ clast_to_gcc_expression_red (tree type, enum tree_code op,
static tree
clast_to_gcc_expression (tree type, struct clast_expr *e,
sese region, VEC (tree, heap) *newivs,
- htab_t newivs_index)
+ htab_t newivs_index, htab_t params_index)
{
switch (e->type)
{
@@ -173,21 +272,21 @@ clast_to_gcc_expression (tree type, struct clast_expr *e,
if (value_one_p (t->val))
{
tree name = clast_name_to_gcc (t->var, region, newivs,
- newivs_index);
+ newivs_index, params_index);
return fold_convert (type, name);
}
else if (value_mone_p (t->val))
{
tree name = clast_name_to_gcc (t->var, region, newivs,
- newivs_index);
+ newivs_index, params_index);
name = fold_convert (type, name);
return fold_build1 (NEGATE_EXPR, type, name);
}
else
{
tree name = clast_name_to_gcc (t->var, region, newivs,
- newivs_index);
+ newivs_index, params_index);
tree cst = gmp_cst_to_tree (type, t->val);
name = fold_convert (type, name);
return fold_build2 (MULT_EXPR, type, cst, name);
@@ -206,15 +305,17 @@ clast_to_gcc_expression (tree type, struct clast_expr *e,
case clast_red_sum:
return clast_to_gcc_expression_red
(type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
- r, region, newivs, newivs_index);
+ r, region, newivs, newivs_index, params_index);
case clast_red_min:
return clast_to_gcc_expression_red (type, MIN_EXPR, r, region,
- newivs, newivs_index);
+ newivs, newivs_index,
+ params_index);
case clast_red_max:
return clast_to_gcc_expression_red (type, MAX_EXPR, r, region,
- newivs, newivs_index);
+ newivs, newivs_index,
+ params_index);
default:
gcc_unreachable ();
@@ -227,7 +328,7 @@ clast_to_gcc_expression (tree type, struct clast_expr *e,
struct clast_binary *b = (struct clast_binary *) e;
struct clast_expr *lhs = (struct clast_expr *) b->LHS;
tree tl = clast_to_gcc_expression (type, lhs, region, newivs,
- newivs_index);
+ newivs_index, params_index);
tree tr = gmp_cst_to_tree (type, b->RHS);
switch (b->type)
@@ -261,7 +362,7 @@ clast_to_gcc_expression (tree type, struct clast_expr *e,
static tree
gcc_type_for_clast_expr (struct clast_expr *e,
sese region, VEC (tree, heap) *newivs,
- htab_t newivs_index)
+ htab_t newivs_index, htab_t params_index)
{
switch (e->type)
{
@@ -271,7 +372,7 @@ gcc_type_for_clast_expr (struct clast_expr *e,
if (t->var)
return TREE_TYPE (clast_name_to_gcc (t->var, region, newivs,
- newivs_index));
+ newivs_index, params_index));
else
return NULL_TREE;
}
@@ -282,14 +383,15 @@ gcc_type_for_clast_expr (struct clast_expr *e,
if (r->n == 1)
return gcc_type_for_clast_expr (r->elts[0], region, newivs,
- newivs_index);
+ newivs_index, params_index);
else
{
int i;
for (i = 0; i < r->n; i++)
{
tree type = gcc_type_for_clast_expr (r->elts[i], region,
- newivs, newivs_index);
+ newivs, newivs_index,
+ params_index);
if (type)
return type;
}
@@ -302,7 +404,7 @@ gcc_type_for_clast_expr (struct clast_expr *e,
struct clast_binary *b = (struct clast_binary *) e;
struct clast_expr *lhs = (struct clast_expr *) b->LHS;
return gcc_type_for_clast_expr (lhs, region, newivs,
- newivs_index);
+ newivs_index, params_index);
}
default:
@@ -317,14 +419,15 @@ gcc_type_for_clast_expr (struct clast_expr *e,
static tree
gcc_type_for_clast_eq (struct clast_equation *cleq,
sese region, VEC (tree, heap) *newivs,
- htab_t newivs_index)
+ htab_t newivs_index, htab_t params_index)
{
tree type = gcc_type_for_clast_expr (cleq->LHS, region, newivs,
- newivs_index);
+ newivs_index, params_index);
if (type)
return type;
- return gcc_type_for_clast_expr (cleq->RHS, region, newivs, newivs_index);
+ return gcc_type_for_clast_expr (cleq->RHS, region, newivs, newivs_index,
+ params_index);
}
/* Translates a clast equation CLEQ to a tree. */
@@ -333,14 +436,15 @@ static tree
graphite_translate_clast_equation (sese region,
struct clast_equation *cleq,
VEC (tree, heap) *newivs,
- htab_t newivs_index)
+ htab_t newivs_index, htab_t params_index)
{
enum tree_code comp;
- tree type = gcc_type_for_clast_eq (cleq, region, newivs, newivs_index);
+ tree type = gcc_type_for_clast_eq (cleq, region, newivs, newivs_index,
+ params_index);
tree lhs = clast_to_gcc_expression (type, cleq->LHS, region, newivs,
- newivs_index);
+ newivs_index, params_index);
tree rhs = clast_to_gcc_expression (type, cleq->RHS, region, newivs,
- newivs_index);
+ newivs_index, params_index);
if (cleq->sign == 0)
comp = EQ_EXPR;
@@ -359,7 +463,7 @@ graphite_translate_clast_equation (sese region,
static tree
graphite_create_guard_cond_expr (sese region, struct clast_guard *stmt,
VEC (tree, heap) *newivs,
- htab_t newivs_index)
+ htab_t newivs_index, htab_t params_index)
{
tree cond = NULL;
int i;
@@ -367,7 +471,8 @@ graphite_create_guard_cond_expr (sese region, struct clast_guard *stmt,
for (i = 0; i < stmt->n; i++)
{
tree eq = graphite_translate_clast_equation (region, &stmt->eq[i],
- newivs, newivs_index);
+ newivs, newivs_index,
+ params_index);
if (cond)
cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
@@ -384,10 +489,10 @@ static edge
graphite_create_new_guard (sese region, edge entry_edge,
struct clast_guard *stmt,
VEC (tree, heap) *newivs,
- htab_t newivs_index)
+ htab_t newivs_index, htab_t params_index)
{
tree cond_expr = graphite_create_guard_cond_expr (region, stmt, newivs,
- newivs_index);
+ newivs_index, params_index);
edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
return exit_edge;
}
@@ -460,13 +565,13 @@ static struct loop *
graphite_create_new_loop (sese region, edge entry_edge,
struct clast_for *stmt,
loop_p outer, VEC (tree, heap) **newivs,
- htab_t newivs_index)
+ htab_t newivs_index, htab_t params_index)
{
tree type = gcc_type_for_iv_of_clast_loop (stmt);
tree lb = clast_to_gcc_expression (type, stmt->LB, region, *newivs,
- newivs_index);
+ newivs_index, params_index);
tree ub = clast_to_gcc_expression (type, stmt->UB, region, *newivs,
- newivs_index);
+ newivs_index, params_index);
tree stride = gmp_cst_to_tree (type, stmt->stride);
tree ivvar = create_tmp_var (type, "graphite_IV");
tree iv, iv_after_increment;
@@ -488,7 +593,8 @@ graphite_create_new_loop (sese region, edge entry_edge,
static void
build_iv_mapping (htab_t map, sese region,
VEC (tree, heap) *newivs, htab_t newivs_index,
- struct clast_user_stmt *user_stmt)
+ struct clast_user_stmt *user_stmt,
+ htab_t params_index)
{
struct clast_stmt *t;
int index = 0;
@@ -500,10 +606,10 @@ build_iv_mapping (htab_t map, sese region,
struct clast_expr *expr = (struct clast_expr *)
((struct clast_assignment *)t)->RHS;
tree type = gcc_type_for_clast_expr (expr, region, newivs,
- newivs_index);
+ newivs_index, params_index);
tree old_name = pbb_to_depth_to_oldiv (pbb, index);
tree e = clast_to_gcc_expression (type, expr, region, newivs,
- newivs_index);
+ newivs_index, params_index);
set_rename (map, old_name, e);
}
}
@@ -612,135 +718,256 @@ dependency_in_loop_p (loop_p loop, htab_t bb_pbb_mapping, int level)
return false;
}
-/* Translates a CLAST statement STMT to GCC representation in the
- context of a SESE.
+static edge
+translate_clast (sese, struct clast_stmt *, edge, htab_t, VEC (tree, heap) **,
+ htab_t, htab_t, htab_t);
+
+/* Translates a clast user statement STMT to gimple.
+ - REGION is the sese region we used to generate the scop.
- NEXT_E is the edge where new generated code should be attached.
- - CONTEXT_LOOP is the loop in which the generated code will be placed
- RENAME_MAP contains a set of tuples of new names associated to
the original variables names.
- BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
-*/
-
+ - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
+ the sese region. */
static edge
-translate_clast (sese region, struct loop *context_loop,
- struct clast_stmt *stmt, edge next_e,
- htab_t rename_map, VEC (tree, heap) **newivs,
- htab_t newivs_index, htab_t bb_pbb_mapping, int level)
+translate_clast_user (sese region, struct clast_user_stmt *stmt, edge next_e,
+ htab_t rename_map, VEC (tree, heap) **newivs,
+ htab_t newivs_index, htab_t bb_pbb_mapping,
+ htab_t params_index)
{
- if (!stmt)
+ poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (stmt->statement);
+ gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
+
+ if (GBB_BB (gbb) == ENTRY_BLOCK_PTR)
return next_e;
- if (CLAST_STMT_IS_A (stmt, stmt_root))
- return translate_clast (region, context_loop, stmt->next, next_e,
- rename_map, newivs, newivs_index,
- bb_pbb_mapping, level);
+ build_iv_mapping (rename_map, region, *newivs, newivs_index, stmt,
+ params_index);
+ next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), region,
+ next_e, rename_map);
+ mark_bb_with_pbb (pbb, next_e->src, bb_pbb_mapping);
+ update_ssa (TODO_update_ssa);
- if (CLAST_STMT_IS_A (stmt, stmt_user))
- {
- gimple_bb_p gbb;
- basic_block new_bb;
- CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
- poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
- gbb = PBB_BLACK_BOX (pbb);
-
- if (GBB_BB (gbb) == ENTRY_BLOCK_PTR)
- return next_e;
-
- build_iv_mapping (rename_map, region, *newivs, newivs_index,
- (struct clast_user_stmt *) stmt);
- next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), region,
- next_e, rename_map);
- new_bb = next_e->src;
- mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
- recompute_all_dominators ();
- update_ssa (TODO_update_ssa);
- graphite_verify ();
- return translate_clast (region, context_loop, stmt->next, next_e,
- rename_map, newivs, newivs_index,
- bb_pbb_mapping, level);
- }
+ return next_e;
+}
- if (CLAST_STMT_IS_A (stmt, stmt_for))
- {
- struct clast_for *stmtfor = (struct clast_for *)stmt;
- struct loop *loop
- = graphite_create_new_loop (region, next_e, stmtfor,
- context_loop, newivs, newivs_index);
- edge last_e = single_exit (loop);
- edge to_body = single_succ_edge (loop->header);
- basic_block after = to_body->dest;
-
- /* Create a basic block for loop close phi nodes. */
- last_e = single_succ_edge (split_edge (last_e));
-
- /* Translate the body of the loop. */
- next_e = translate_clast
- (region, loop, ((struct clast_for *) stmt)->body,
- single_succ_edge (loop->header), rename_map, newivs,
- newivs_index, bb_pbb_mapping, level + 1);
- redirect_edge_succ_nodup (next_e, after);
- set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
-
- /* Remove from rename_map all the tuples containing variables
- defined in loop's body. */
- insert_loop_close_phis (rename_map, loop);
-
- if (flag_loop_parallelize_all
- && !dependency_in_loop_p (loop, bb_pbb_mapping,
- get_scattering_level (level)))
- loop->can_be_parallel = true;
-
- recompute_all_dominators ();
- graphite_verify ();
- return translate_clast (region, context_loop, stmt->next, last_e,
- rename_map, newivs, newivs_index,
- bb_pbb_mapping, level);
- }
+/* Mark a loop parallel, if the graphite dependency check cannot find any
+ dependencies. This triggers parallel code generation in the autopar pass.
+ */
+static void
+try_mark_loop_parallel (sese region, loop_p loop, htab_t bb_pbb_mapping)
+{
+ loop_p outermost_loop = SESE_ENTRY (region)->src->loop_father;
+ int level = loop_depth (loop) - loop_depth (outermost_loop);
- if (CLAST_STMT_IS_A (stmt, stmt_guard))
- {
- edge last_e = graphite_create_new_guard (region, next_e,
- ((struct clast_guard *) stmt),
- *newivs, newivs_index);
- edge true_e = get_true_edge_from_guard_bb (next_e->dest);
- edge false_e = get_false_edge_from_guard_bb (next_e->dest);
- edge exit_true_e = single_succ_edge (true_e->dest);
- edge exit_false_e = single_succ_edge (false_e->dest);
- htab_t before_guard = htab_create (10, rename_map_elt_info,
- eq_rename_map_elts, free);
-
- htab_traverse (rename_map, copy_renames, before_guard);
- next_e = translate_clast (region, context_loop,
- ((struct clast_guard *) stmt)->then,
- true_e, rename_map, newivs, newivs_index,
- bb_pbb_mapping, level);
- insert_guard_phis (last_e->src, exit_true_e, exit_false_e,
- before_guard, rename_map);
-
- htab_delete (before_guard);
- recompute_all_dominators ();
- graphite_verify ();
-
- return translate_clast (region, context_loop, stmt->next, last_e,
- rename_map, newivs, newivs_index,
- bb_pbb_mapping, level);
- }
+ if (flag_loop_parallelize_all
+ && !dependency_in_loop_p (loop, bb_pbb_mapping,
+ get_scattering_level (level)))
+ loop->can_be_parallel = true;
+}
- if (CLAST_STMT_IS_A (stmt, stmt_block))
- {
- next_e = translate_clast (region, context_loop,
- ((struct clast_block *) stmt)->body,
- next_e, rename_map, newivs, newivs_index,
- bb_pbb_mapping, level);
- recompute_all_dominators ();
- graphite_verify ();
- return translate_clast (region, context_loop, stmt->next, next_e,
- rename_map, newivs, newivs_index,
- bb_pbb_mapping, level);
- }
+static tree gcc_type_for_iv_of_clast_loop (struct clast_for *);
- gcc_unreachable ();
+
+/* Creates a new if region protecting the loop to be executed, if the execution
+ count is zero (lb > ub). */
+static edge
+graphite_create_new_loop_guard (sese region, edge entry_edge,
+ struct clast_for *stmt,
+ VEC (tree, heap) *newivs,
+ htab_t newivs_index, htab_t params_index)
+{
+ tree cond_expr;
+ edge exit_edge;
+ tree type = gcc_type_for_iv_of_clast_loop (stmt);
+ tree lb = clast_to_gcc_expression (type, stmt->LB, region, newivs,
+ newivs_index, params_index);
+ tree ub = clast_to_gcc_expression (type, stmt->UB, region, newivs,
+ newivs_index, params_index);
+
+ /* XXX: Adding +1 and using LT_EXPR helps with loop latches that have a
+ loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
+ 2^{32|64}, and the condition lb <= ub is true, even if we do not want this.
+ However lb < ub + 1 is false, as expected.
+ There might be a problem with cases where ub is 2^32. */
+ tree one;
+ Value gmp_one;
+ value_init (gmp_one);
+ value_set_si (gmp_one, 1);
+ one = gmp_cst_to_tree (type, gmp_one);
+ value_clear (gmp_one);
+
+ ub = fold_build2 (PLUS_EXPR, type, ub, one);
+ cond_expr = fold_build2 (LT_EXPR, boolean_type_node, lb, ub);
+
+ exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
+
+ return exit_edge;
+}
+
+
+/* Create the loop for a clast for statement.
+
+ - REGION is the sese region we used to generate the scop.
+ - NEXT_E is the edge where new generated code should be attached.
+ - RENAME_MAP contains a set of tuples of new names associated to
+ the original variables names.
+ - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
+ - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
+ the sese region. */
+static edge
+translate_clast_for_loop (sese region, struct clast_for *stmt, edge next_e,
+ htab_t rename_map, VEC (tree, heap) **newivs,
+ htab_t newivs_index, htab_t bb_pbb_mapping,
+ htab_t params_index)
+{
+ loop_p context_loop = next_e->dest->loop_father;
+ loop_p loop = graphite_create_new_loop (region, next_e, stmt, context_loop,
+ newivs, newivs_index, params_index);
+ edge last_e = single_exit (loop);
+ edge body = single_succ_edge (loop->header);
+
+ next_e = translate_clast (region, stmt->body, body, rename_map, newivs,
+ newivs_index, bb_pbb_mapping, params_index);
+
+ /* Create a basic block for loop close phi nodes. */
+ last_e = single_succ_edge (split_edge (last_e));
+ insert_loop_close_phis (rename_map, loop);
+
+ try_mark_loop_parallel (region, loop, bb_pbb_mapping);
+
+ return last_e;
+}
+
+/* Translates a clast for statement STMT to gimple. First a guard is created
+ protecting the loop, if it is executed zero times. In this guard we create
+ the real loop structure.
+
+ - REGION is the sese region we used to generate the scop.
+ - NEXT_E is the edge where new generated code should be attached.
+ - RENAME_MAP contains a set of tuples of new names associated to
+ the original variables names.
+ - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
+ - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
+ the sese region. */
+static edge
+translate_clast_for (sese region, struct clast_for *stmt, edge next_e,
+ htab_t rename_map, VEC (tree, heap) **newivs,
+ htab_t newivs_index, htab_t bb_pbb_mapping,
+ htab_t params_index)
+{
+ edge last_e = graphite_create_new_loop_guard (region, next_e, stmt, *newivs,
+ newivs_index, params_index);
+
+ edge true_e = get_true_edge_from_guard_bb (next_e->dest);
+ edge false_e = get_false_edge_from_guard_bb (next_e->dest);
+ edge exit_true_e = single_succ_edge (true_e->dest);
+ edge exit_false_e = single_succ_edge (false_e->dest);
+
+ htab_t before_guard = htab_create (10, rename_map_elt_info,
+ eq_rename_map_elts, free);
+ htab_traverse (rename_map, copy_renames, before_guard);
+
+ next_e = translate_clast_for_loop (region, stmt, true_e, rename_map, newivs,
+ newivs_index, bb_pbb_mapping,
+ params_index);
+
+ insert_guard_phis (last_e->src, exit_true_e, exit_false_e,
+ before_guard, rename_map);
+
+ htab_delete (before_guard);
+
+ return last_e;
+}
+
+/* Translates a clast guard statement STMT to gimple.
+
+ - REGION is the sese region we used to generate the scop.
+ - NEXT_E is the edge where new generated code should be attached.
+ - RENAME_MAP contains a set of tuples of new names associated to
+ the original variables names.
+ - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
+ - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
+ the sese region. */
+static edge
+translate_clast_guard (sese region, struct clast_guard *stmt, edge next_e,
+ htab_t rename_map, VEC (tree, heap) **newivs,
+ htab_t newivs_index, htab_t bb_pbb_mapping,
+ htab_t params_index)
+{
+ edge last_e = graphite_create_new_guard (region, next_e, stmt, *newivs,
+ newivs_index, params_index);
+
+ edge true_e = get_true_edge_from_guard_bb (next_e->dest);
+ edge false_e = get_false_edge_from_guard_bb (next_e->dest);
+ edge exit_true_e = single_succ_edge (true_e->dest);
+ edge exit_false_e = single_succ_edge (false_e->dest);
+
+ htab_t before_guard = htab_create (10, rename_map_elt_info,
+ eq_rename_map_elts, free);
+ htab_traverse (rename_map, copy_renames, before_guard);
+
+ next_e = translate_clast (region, stmt->then, true_e,
+ rename_map, newivs, newivs_index, bb_pbb_mapping,
+ params_index);
+
+ insert_guard_phis (last_e->src, exit_true_e, exit_false_e,
+ before_guard, rename_map);
+
+ htab_delete (before_guard);
+
+ return last_e;
+}
+
+/* Translates a CLAST statement STMT to GCC representation in the
+ context of a SESE.
+
+ - NEXT_E is the edge where new generated code should be attached.
+ - RENAME_MAP contains a set of tuples of new names associated to
+ the original variables names.
+ - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
+static edge
+translate_clast (sese region, struct clast_stmt *stmt,
+ edge next_e, htab_t rename_map, VEC (tree, heap) **newivs,
+ htab_t newivs_index, htab_t bb_pbb_mapping,
+ htab_t params_index)
+{
+ if (!stmt)
+ return next_e;
+
+ if (CLAST_STMT_IS_A (stmt, stmt_root))
+ ; /* Do nothing. */
+
+ else if (CLAST_STMT_IS_A (stmt, stmt_user))
+ next_e = translate_clast_user (region, (struct clast_user_stmt *) stmt,
+ next_e, rename_map, newivs, newivs_index,
+ bb_pbb_mapping, params_index);
+
+ else if (CLAST_STMT_IS_A (stmt, stmt_for))
+ next_e = translate_clast_for (region,
+ (struct clast_for *) stmt, next_e, rename_map,
+ newivs, newivs_index, bb_pbb_mapping,
+ params_index);
+
+ else if (CLAST_STMT_IS_A (stmt, stmt_guard))
+ next_e = translate_clast_guard (region, (struct clast_guard *) stmt, next_e,
+ rename_map, newivs, newivs_index,
+ bb_pbb_mapping, params_index);
+
+ else if (CLAST_STMT_IS_A (stmt, stmt_block))
+ next_e = translate_clast (region, ((struct clast_block *) stmt)->body,
+ next_e, rename_map, newivs, newivs_index,
+ bb_pbb_mapping, params_index);
+ else
+ gcc_unreachable();
+
+ recompute_all_dominators ();
+ graphite_verify ();
+
+ return translate_clast (region, stmt->next, next_e, rename_map, newivs,
+ newivs_index, bb_pbb_mapping, params_index);
}
/* Returns the first cloog name used in EXPR. */
@@ -890,14 +1117,30 @@ initialize_cloog_names (scop_p scop, CloogProgram *prog)
int i;
int nb_iterators = scop_max_loop_depth (scop);
int nb_scattering = cloog_program_nb_scattdims (prog);
+ int nb_parameters = VEC_length (tree, SESE_PARAMS (region));
char **iterators = XNEWVEC (char *, nb_iterators * 2);
char **scattering = XNEWVEC (char *, nb_scattering);
+ char **parameters= XNEWVEC (char *, nb_parameters);
cloog_program_set_names (prog, cloog_names_malloc ());
- cloog_names_set_nb_parameters (cloog_program_names (prog),
- VEC_length (tree, SESE_PARAMS (region)));
- cloog_names_set_parameters (cloog_program_names (prog),
- SESE_PARAMS_NAMES (region));
+
+ for (i = 0; i < nb_parameters; i++)
+ {
+ tree param = VEC_index (tree, SESE_PARAMS(region), i);
+ const char *name = get_name (param);
+ int len;
+
+ if (!name)
+ name = "T";
+
+ len = strlen (name);
+ len += 17;
+ parameters[i] = XNEWVEC (char, len + 1);
+ snprintf (parameters[i], len, "%s_%d", name, SSA_NAME_VERSION (param));
+ }
+
+ cloog_names_set_nb_parameters (cloog_program_names (prog), nb_parameters);
+ cloog_names_set_parameters (cloog_program_names (prog), parameters);
for (i = 0; i < nb_iterators; i++)
{
@@ -1144,6 +1387,20 @@ debug_generated_program (scop_p scop)
print_generated_program (stderr, scop);
}
+/* Add CLooG names to parameter index. The index is used to translate back from
+ * CLooG names to GCC trees. */
+
+static void
+create_params_index (htab_t index_table, CloogProgram *prog) {
+ CloogNames* names = cloog_program_names (prog);
+ int nb_parameters = cloog_names_nb_parameters (names);
+ char **parameters = cloog_names_parameters (names);
+ int i;
+
+ for (i = 0; i < nb_parameters; i++)
+ save_clast_name_index (index_table, parameters[i], i);
+}
+
/* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
the given SCOP. Return true if code generation succeeded.
BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
@@ -1154,10 +1411,9 @@ gloog (scop_p scop, htab_t bb_pbb_mapping)
{
edge new_scop_exit_edge = NULL;
VEC (tree, heap) *newivs = VEC_alloc (tree, heap, 10);
- loop_p context_loop;
sese region = SCOP_REGION (scop);
ifsese if_region = NULL;
- htab_t rename_map, newivs_index;
+ htab_t rename_map, newivs_index, params_index;
cloog_prog_clast pc;
timevar_push (TV_GRAPHITE_CODE_GEN);
@@ -1179,20 +1435,22 @@ gloog (scop_p scop, htab_t bb_pbb_mapping)
if_region->region->exit->src,
if_region->false_region->exit,
if_region->true_region->exit);
-
recompute_all_dominators ();
graphite_verify ();
- context_loop = SESE_ENTRY (region)->src->loop_father;
- compute_cloog_iv_types (pc.stmt);
+ compute_cloog_iv_types (pc.stmt);
rename_map = htab_create (10, rename_map_elt_info, eq_rename_map_elts, free);
newivs_index = htab_create (10, clast_name_index_elt_info,
eq_clast_name_indexes, free);
+ params_index = htab_create (10, clast_name_index_elt_info,
+ eq_clast_name_indexes, free);
+
+ create_params_index (params_index, pc.prog);
- new_scop_exit_edge = translate_clast (region, context_loop, pc.stmt,
+ new_scop_exit_edge = translate_clast (region, pc.stmt,
if_region->true_region->entry,
rename_map, &newivs, newivs_index,
- bb_pbb_mapping, 1);
+ bb_pbb_mapping, params_index);
graphite_verify ();
sese_adjust_liveout_phis (region, rename_map,
if_region->region->exit->src,
@@ -1207,6 +1465,7 @@ gloog (scop_p scop, htab_t bb_pbb_mapping)
htab_delete (rename_map);
htab_delete (newivs_index);
+ htab_delete (params_index);
VEC_free (tree, heap, newivs);
cloog_clast_free (pc.stmt);
cloog_program_free (pc.prog);
diff --git a/gcc/graphite-scop-detection.c b/gcc/graphite-scop-detection.c
index 6580252a7fa..02c653b69a6 100644
--- a/gcc/graphite-scop-detection.c
+++ b/gcc/graphite-scop-detection.c
@@ -1207,24 +1207,6 @@ print_graphite_statistics (FILE* file, VEC (scop_p, heap) *scops)
print_graphite_scop_statistics (file, scop);
}
-/* Version of free_scops special cased for limit_scops. */
-
-static void
-free_scops_1 (VEC (scop_p, heap) **scops)
-{
- int i;
- scop_p scop;
-
- for (i = 0; VEC_iterate (scop_p, *scops, i, scop); i++)
- {
- sese region = SCOP_REGION (scop);
- free (SESE_PARAMS_NAMES (region));
- SESE_PARAMS_NAMES (region) = 0;
- }
-
- free_scops (*scops);
-}
-
/* We limit all SCoPs to SCoPs, that are completely surrounded by a loop.
Example:
@@ -1278,7 +1260,7 @@ limit_scops (VEC (scop_p, heap) **scops)
}
}
- free_scops_1 (scops);
+ free_scops (*scops);
*scops = VEC_alloc (scop_p, heap, 3);
create_sese_edges (regions);
diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c
index d3a24037954..37b20354d6f 100644
--- a/gcc/graphite-sese-to-poly.c
+++ b/gcc/graphite-sese-to-poly.c
@@ -746,26 +746,6 @@ scan_tree_for_params_int (tree cst, ppl_Linear_Expression_t expr, Value k)
ppl_delete_Coefficient (coef);
}
-/* Saves in NV at index I a new name for variable P. */
-
-static void
-save_var_name (char **nv, int i, tree p)
-{
- const char *name = get_name (SSA_NAME_VAR (p));
-
- if (name)
- {
- int len = strlen (name) + 16;
- nv[i] = XNEWVEC (char, len);
- snprintf (nv[i], len, "%s_%d", name, SSA_NAME_VERSION (p));
- }
- else
- {
- nv[i] = XNEWVEC (char, 16);
- snprintf (nv[i], 2 + 16, "T_%d", SSA_NAME_VERSION (p));
- }
-}
-
/* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
Otherwise returns -1. */
@@ -802,9 +782,6 @@ parameter_index_in_region (tree name, sese region)
gcc_assert (SESE_ADD_PARAMS (region));
i = VEC_length (tree, SESE_PARAMS (region));
- save_var_name (SESE_PARAMS_NAMES (region), i, name);
- save_clast_name_index (SESE_PARAMS_INDEX (region),
- SESE_PARAMS_NAMES (region)[i], i);
VEC_safe_push (tree, heap, SESE_PARAMS (region), name);
return i;
}
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 6a018f456ea..9387f0e0779 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -754,6 +754,7 @@ ipa_note_param_call (struct ipa_node_params *info, int formal_id,
note->lto_stmt_uid = gimple_uid (stmt);
note->count = bb->count;
note->frequency = compute_call_stmt_bb_frequency (current_function_decl, bb);
+ note->loop_nest = bb->loop_depth;
note->next = info->param_calls;
info->param_calls = note;
@@ -2008,7 +2009,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
int j;
struct cgraph_edge *e;
struct bitpack_d *bp;
- int note_count;
+ int note_count = 0;
struct ipa_param_call_note *note;
encoder = ob->decl_state->cgraph_node_encoder;
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 4dc87d78503..90055e124bc 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -139,6 +139,8 @@ struct ipcp_lattice
are linked in a list. */
struct ipa_param_call_note
{
+ /* Expected number of executions: calculated in profile.c. */
+ gcov_type count;
/* Linked list's next */
struct ipa_param_call_note *next;
/* Statement that contains the call to the parameter above. */
@@ -147,13 +149,11 @@ struct ipa_param_call_note
unsigned int lto_stmt_uid;
/* Index of the parameter that is called. */
int formal_id;
- /* Expected number of executions: calculated in profile.c. */
- gcov_type count;
/* Expected frequency of executions within the function. see cgraph_edge in
cgraph.h for more on this. */
int frequency;
/* Depth of loop nest, 1 means no loop nest. */
- int loop_nest;
+ unsigned short int loop_nest;
/* Set when we have already found the target to be a compile time constant
and turned this into an edge or when the note was found unusable for some
reason. */
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index 032bef278eb..98a4ce7d714 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -1389,22 +1389,23 @@ propagate (void)
ipa_reference_local_vars_info_t w_l = w_ri->local;
fprintf (dump_file, "\n next cycle: %s/%i ",
cgraph_node_name (w), w->uid);
- fprintf (dump_file, "\n locals read: ");
- EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
- 0, index, bi)
- {
- fprintf (dump_file, "%s ",
- get_static_name (index));
- }
+ fprintf (dump_file, "\n locals read: ");
+ if (w_l->statics_read)
+ EXECUTE_IF_SET_IN_BITMAP (w_l->statics_read,
+ 0, index, bi)
+ {
+ fprintf (dump_file, "%s ",
+ get_static_name (index));
+ }
fprintf (dump_file, "\n locals written: ");
- EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
- 0, index, bi)
- {
- fprintf(dump_file, "%s ",
- get_static_name (index));
- }
-
+ if (w_l->statics_written)
+ EXECUTE_IF_SET_IN_BITMAP (w_l->statics_written,
+ 0, index, bi)
+ {
+ fprintf (dump_file, "%s ",
+ get_static_name (index));
+ }
w_info = (struct ipa_dfs_info *) w->aux;
w = w_info->next_cycle;
diff --git a/gcc/ipa-struct-reorg.c b/gcc/ipa-struct-reorg.c
index 0cb7ccca31b..e1dddae999e 100644
--- a/gcc/ipa-struct-reorg.c
+++ b/gcc/ipa-struct-reorg.c
@@ -569,7 +569,7 @@ static new_var
is_in_new_vars_htab (tree decl, htab_t new_vars_htab)
{
return (new_var) htab_find_with_hash (new_vars_htab, decl,
- htab_hash_pointer (decl));
+ DECL_UID (decl));
}
/* Given original variable ORIG_VAR, this function returns
@@ -1962,7 +1962,7 @@ add_to_new_vars_htab (new_var new_node, htab_t new_vars_htab)
void **slot;
slot = htab_find_slot_with_hash (new_vars_htab, new_node->orig_var,
- htab_hash_pointer (new_node->orig_var),
+ DECL_UID (new_node->orig_var),
INSERT);
*slot = new_node;
}
@@ -2254,15 +2254,19 @@ create_new_var (tree var_decl, htab_t new_vars_htab)
static hashval_t
new_var_hash (const void *x)
{
- return htab_hash_pointer (((const_new_var)x)->orig_var);
+ return DECL_UID (((const_new_var)x)->orig_var);
}
-/* This function returns nonzero if orig_var of new_var X is equal to Y. */
+/* This function returns nonzero if orig_var of new_var X
+ and tree Y have equal UIDs. */
static int
new_var_eq (const void *x, const void *y)
{
- return ((const_new_var)x)->orig_var == (const_tree)y;
+ if (DECL_P ((const_tree)y))
+ return DECL_UID (((const_new_var)x)->orig_var) == DECL_UID ((const_tree)y);
+ else
+ return 0;
}
/* This function check whether a structure type represented by STR
diff --git a/gcc/params.c b/gcc/params.c
index d7179c085fc..04eff112055 100644
--- a/gcc/params.c
+++ b/gcc/params.c
@@ -32,7 +32,6 @@ along with GCC; see the file COPYING3. If not see
param_info *compiler_params;
/* The number of entries in the table. */
-
static size_t num_compiler_params;
/* Add the N PARAMS to the current list of compiler parameters. */
@@ -85,3 +84,12 @@ set_param_value (const char *name, int value)
/* If we didn't find this parameter, issue an error message. */
error ("invalid parameter %qs", name);
}
+
+/* Return the current value of num_compiler_params, for the benefit of
+ plugins that use parameters as features. */
+
+size_t
+get_num_compiler_params (void)
+{
+ return num_compiler_params;
+}
diff --git a/gcc/params.h b/gcc/params.h
index e0bb4fa7e9b..833fc3bb2f1 100644
--- a/gcc/params.h
+++ b/gcc/params.h
@@ -65,6 +65,9 @@ typedef struct param_info
extern param_info *compiler_params;
+/* Returns the number of entries in the table, for the use by plugins. */
+extern size_t get_num_compiler_params (void);
+
/* Add the N PARAMS to the current list of compiler parameters. */
extern void add_params (const param_info params[], size_t n);
diff --git a/gcc/passes.c b/gcc/passes.c
index 57b55c08fc9..818adde18e0 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -85,6 +85,7 @@ along with GCC; see the file COPYING3. If not see
#include "df.h"
#include "predict.h"
#include "lto-streamer.h"
+#include "plugin.h"
#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
#include "dwarf2out.h"
@@ -104,7 +105,8 @@ along with GCC; see the file COPYING3. If not see
#endif
/* This is used for debugging. It allows the current pass to printed
- from anywhere in compilation. */
+ from anywhere in compilation.
+ The variable current_pass is also used for statistics and plugins. */
struct opt_pass *current_pass;
/* Call from anywhere to find out what pass this is. Useful for
@@ -479,6 +481,8 @@ make_pass_instance (struct opt_pass *pass, bool track_duplicates)
{
pass->todo_flags_start |= TODO_mark_first_instance;
pass->static_pass_number = -1;
+
+ invoke_plugin_callbacks (PLUGIN_NEW_PASS, pass);
}
return pass;
}
@@ -1090,9 +1094,9 @@ static GTY ((length ("nnodes"))) struct cgraph_node **order;
/* If we are in IPA mode (i.e., current_function_decl is NULL), call
function CALLBACK for every function in the call graph. Otherwise,
- call CALLBACK on the current function. */
-
-static void
+ call CALLBACK on the current function.
+ This function is global so that plugins can use it. */
+void
do_per_function_toporder (void (*callback) (void *data), void *data)
{
int i;
@@ -1317,8 +1321,9 @@ verify_curr_properties (void *data)
#endif
/* Initialize pass dump file. */
+/* This is non-static so that the plugins can use it. */
-static bool
+bool
pass_init_dump_file (struct opt_pass *pass)
{
/* If a dump file name is present, open it if enabled. */
@@ -1347,8 +1352,9 @@ pass_init_dump_file (struct opt_pass *pass)
}
/* Flush PASS dump file. */
+/* This is non-static so that plugins can use it. */
-static void
+void
pass_fini_dump_file (struct opt_pass *pass)
{
/* Flush and close dump file. */
@@ -1476,12 +1482,14 @@ execute_all_ipa_transforms (void)
/* Execute PASS. */
-static bool
+bool
execute_one_pass (struct opt_pass *pass)
{
bool initializing_dump;
unsigned int todo_after = 0;
+ bool gate_status;
+
/* IPA passes are executed on whole program, so cfun should be NULL.
Other passes need function context set. */
if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
@@ -1491,9 +1499,22 @@ execute_one_pass (struct opt_pass *pass)
current_pass = pass;
- /* See if we're supposed to run this pass. */
- if (pass->gate && !pass->gate ())
- return false;
+ /* Check whether gate check should be avoided.
+ User controls the value of the gate through the parameter "gate_status". */
+ gate_status = (pass->gate == NULL) ? true : pass->gate();
+
+ /* Override gate with plugin. */
+ invoke_plugin_callbacks (PLUGIN_OVERRIDE_GATE, &gate_status);
+
+ if (!gate_status)
+ {
+ current_pass = NULL;
+ return false;
+ }
+
+ /* Pass execution event trigger: useful to identify passes being
+ executed. */
+ invoke_plugin_callbacks (PLUGIN_PASS_EXECUTION, pass);
if (!quiet_flag && !cfun)
fprintf (stderr, " <%s>", pass->name ? pass->name : "");
@@ -1756,8 +1777,12 @@ execute_ipa_pass_list (struct opt_pass *pass)
if (execute_one_pass (pass) && pass->sub)
{
if (pass->sub->type == GIMPLE_PASS)
- do_per_function_toporder ((void (*)(void *))execute_pass_list,
- pass->sub);
+ {
+ invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_START, NULL);
+ do_per_function_toporder ((void (*)(void *))execute_pass_list,
+ pass->sub);
+ invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_END, NULL);
+ }
else if (pass->sub->type == SIMPLE_IPA_PASS
|| pass->sub->type == IPA_PASS)
execute_ipa_pass_list (pass->sub);
diff --git a/gcc/plugin.c b/gcc/plugin.c
index 750f537a222..673ad07ffc5 100644
--- a/gcc/plugin.c
+++ b/gcc/plugin.c
@@ -44,30 +44,32 @@ along with GCC; see the file COPYING3. If not see
#include "plugin-version.h"
#endif
+#define GCC_PLUGIN_STRINGIFY0(X) #X
+#define GCC_PLUGIN_STRINGIFY1(X) GCC_PLUGIN_STRINGIFY0 (X)
+
/* Event names as strings. Keep in sync with enum plugin_event. */
-const char *plugin_event_name[] =
+static const char *plugin_event_name_init[] =
{
- "PLUGIN_PASS_MANAGER_SETUP",
- "PLUGIN_FINISH_TYPE",
- "PLUGIN_FINISH_UNIT",
- "PLUGIN_CXX_CP_PRE_GENERICIZE",
- "PLUGIN_FINISH",
- "PLUGIN_INFO",
- "PLUGIN_GGC_START",
- "PLUGIN_GGC_MARKING",
- "PLUGIN_GGC_END",
- "PLUGIN_REGISTER_GGC_ROOTS",
- "PLUGIN_REGISTER_GGC_CACHES",
- "PLUGIN_ATTRIBUTES",
- "PLUGIN_START_UNIT",
- "PLUGIN_PRAGMAS",
- "PLUGIN_EVENT_LAST"
+# define DEFEVENT(NAME) GCC_PLUGIN_STRINGIFY1 (NAME),
+# include "plugin.def"
+# undef DEFEVENT
};
/* a printf format large enough for the largest event above */
#define FMT_FOR_PLUGIN_EVENT "%-26s"
/* A printf format large enough for the largest event above. */
-#define FMT_FOR_PLUGIN_EVENT "%-26s"
+#define FMT_FOR_PLUGIN_EVENT "%-32s"
+
+const char **plugin_event_name = plugin_event_name_init;
+
+/* A hash table to map event names to the position of the names in the
+ plugin_event_name table. */
+static htab_t event_tab;
+
+/* Keep track of the limit of allocated events and space ready for
+ allocating events. */
+static int event_last = PLUGIN_EVENT_FIRST_DYNAMIC;
+static int event_horizon = PLUGIN_EVENT_FIRST_DYNAMIC;
/* Hash table for the plugin_name_args objects created during command-line
parsing. */
@@ -83,7 +85,8 @@ struct callback_info
};
/* An array of lists of 'callback_info' objects indexed by the event id. */
-static struct callback_info *plugin_callbacks[PLUGIN_EVENT_LAST] = { NULL };
+static struct callback_info *plugin_callbacks_init[PLUGIN_EVENT_FIRST_DYNAMIC];
+static struct callback_info **plugin_callbacks = plugin_callbacks_init;
#ifdef ENABLE_PLUGIN
@@ -292,6 +295,71 @@ register_plugin_info (const char* name, struct plugin_info *info)
plugin->help = info->help;
}
+/* Helper function for the event hash table that compares the name of an
+ existing entry (E1) with the given string (S2). */
+
+static int
+htab_event_eq (const void *e1, const void *s2)
+{
+ const char *s1= *(const char * const *) e1;
+ return !strcmp (s1, (const char *) s2);
+}
+
+/* Look up the event id for NAME. If the name is not found, return -1
+ if INSERT is NO_INSERT. */
+
+int
+get_named_event_id (const char *name, enum insert_option insert)
+{
+ void **slot;
+
+ if (!event_tab)
+ {
+ int i;
+
+ event_tab = htab_create (150, htab_hash_string, htab_event_eq, NULL);
+ for (i = 0; i < PLUGIN_EVENT_FIRST_DYNAMIC; i++)
+ {
+ slot = htab_find_slot (event_tab, plugin_event_name[i], INSERT);
+ gcc_assert (*slot == HTAB_EMPTY_ENTRY);
+ *slot = &plugin_event_name[i];
+ }
+ }
+ slot = htab_find_slot (event_tab, name, insert);
+ if (slot == NULL)
+ return -1;
+ if (*slot != HTAB_EMPTY_ENTRY)
+ return (const char **) *slot - &plugin_event_name[0];
+
+ if (event_last >= event_horizon)
+ {
+ event_horizon = event_last * 2;
+ if (plugin_event_name == plugin_event_name_init)
+ {
+ plugin_event_name = XNEWVEC (const char *, event_horizon);
+ memcpy (plugin_event_name, plugin_event_name_init,
+ sizeof plugin_event_name_init);
+ plugin_callbacks = XNEWVEC (struct callback_info *, event_horizon);
+ memcpy (plugin_callbacks, plugin_callbacks_init,
+ sizeof plugin_callbacks_init);
+ }
+ else
+ {
+ plugin_event_name
+ = XRESIZEVEC (const char *, plugin_event_name, event_horizon);
+ plugin_callbacks = XRESIZEVEC (struct callback_info *,
+ plugin_callbacks, event_horizon);
+ }
+ /* All the pointers in the hash table will need to be updated. */
+ htab_delete (event_tab);
+ event_tab = NULL;
+ }
+ else
+ *slot = &plugin_event_name[event_last];
+ plugin_event_name[event_last] = name;
+ return event_last++;
+}
+
/* Called from the plugin's initialization code. Register a single callback.
This function can be called multiple times.
@@ -302,7 +370,7 @@ register_plugin_info (const char* name, struct plugin_info *info)
void
register_callback (const char *plugin_name,
- enum plugin_event event,
+ int event,
plugin_callback_func callback,
void *user_data)
{
@@ -324,6 +392,15 @@ register_callback (const char *plugin_name,
gcc_assert (!callback);
ggc_register_cache_tab ((const struct ggc_cache_tab*) user_data);
break;
+ case PLUGIN_EVENT_FIRST_DYNAMIC:
+ default:
+ if (event < PLUGIN_EVENT_FIRST_DYNAMIC || event >= event_last)
+ {
+ error ("Unknown callback event registered by plugin %s",
+ plugin_name);
+ return;
+ }
+ /* Fall through. */
case PLUGIN_FINISH_TYPE:
case PLUGIN_START_UNIT:
case PLUGIN_FINISH_UNIT:
@@ -334,6 +411,15 @@ register_callback (const char *plugin_name,
case PLUGIN_ATTRIBUTES:
case PLUGIN_PRAGMAS:
case PLUGIN_FINISH:
+ case PLUGIN_ALL_PASSES_START:
+ case PLUGIN_ALL_PASSES_END:
+ case PLUGIN_ALL_IPA_PASSES_START:
+ case PLUGIN_ALL_IPA_PASSES_END:
+ case PLUGIN_OVERRIDE_GATE:
+ case PLUGIN_PASS_EXECUTION:
+ case PLUGIN_EARLY_GIMPLE_PASSES_START:
+ case PLUGIN_EARLY_GIMPLE_PASSES_END:
+ case PLUGIN_NEW_PASS:
{
struct callback_info *new_callback;
if (!callback)
@@ -350,27 +436,52 @@ register_callback (const char *plugin_name,
plugin_callbacks[event] = new_callback;
}
break;
- case PLUGIN_EVENT_LAST:
- default:
- error ("Unknown callback event registered by plugin %s",
- plugin_name);
}
}
+/* Remove a callback for EVENT which has been registered with for a plugin
+ PLUGIN_NAME. Return PLUGEVT_SUCCESS if a matching callback was
+ found & removed, PLUGEVT_NO_CALLBACK if the event does not have a matching
+ callback, and PLUGEVT_NO_SUCH_EVENT if EVENT is invalid. */
+int
+unregister_callback (const char *plugin_name, int event)
+{
+ struct callback_info *callback, **cbp;
+
+ if (event >= event_last)
+ return PLUGEVT_NO_SUCH_EVENT;
+
+ for (cbp = &plugin_callbacks[event]; (callback = *cbp); cbp = &callback->next)
+ if (strcmp (callback->plugin_name, plugin_name) == 0)
+ {
+ *cbp = callback->next;
+ return PLUGEVT_SUCCESS;
+ }
+ return PLUGEVT_NO_CALLBACK;
+}
/* Called from inside GCC. Invoke all plug-in callbacks registered with
the specified event.
+ Return PLUGEVT_SUCCESS if at least one callback was called,
+ PLUGEVT_NO_CALLBACK if there was no callback.
EVENT - the event identifier
GCC_DATA - event-specific data provided by the compiler */
-void
-invoke_plugin_callbacks (enum plugin_event event, void *gcc_data)
+int
+invoke_plugin_callbacks (int event, void *gcc_data)
{
+ int retval = PLUGEVT_SUCCESS;
+
timevar_push (TV_PLUGIN_RUN);
switch (event)
{
+ case PLUGIN_EVENT_FIRST_DYNAMIC:
+ default:
+ gcc_assert (event >= PLUGIN_EVENT_FIRST_DYNAMIC);
+ gcc_assert (event < event_last);
+ /* Fall through. */
case PLUGIN_FINISH_TYPE:
case PLUGIN_START_UNIT:
case PLUGIN_FINISH_UNIT:
@@ -381,24 +492,35 @@ invoke_plugin_callbacks (enum plugin_event event, void *gcc_data)
case PLUGIN_GGC_START:
case PLUGIN_GGC_MARKING:
case PLUGIN_GGC_END:
+ case PLUGIN_ALL_PASSES_START:
+ case PLUGIN_ALL_PASSES_END:
+ case PLUGIN_ALL_IPA_PASSES_START:
+ case PLUGIN_ALL_IPA_PASSES_END:
+ case PLUGIN_OVERRIDE_GATE:
+ case PLUGIN_PASS_EXECUTION:
+ case PLUGIN_EARLY_GIMPLE_PASSES_START:
+ case PLUGIN_EARLY_GIMPLE_PASSES_END:
+ case PLUGIN_NEW_PASS:
{
/* Iterate over every callback registered with this event and
call it. */
struct callback_info *callback = plugin_callbacks[event];
+
+ if (!callback)
+ retval = PLUGEVT_NO_CALLBACK;
for ( ; callback; callback = callback->next)
(*callback->func) (gcc_data, callback->user_data);
}
break;
case PLUGIN_PASS_MANAGER_SETUP:
- case PLUGIN_EVENT_LAST:
case PLUGIN_REGISTER_GGC_ROOTS:
case PLUGIN_REGISTER_GGC_CACHES:
- default:
gcc_assert (false);
}
timevar_pop (TV_PLUGIN_RUN);
+ return retval;
}
#ifdef ENABLE_PLUGIN
@@ -623,7 +745,7 @@ plugins_active_p (void)
{
int event;
- for (event = PLUGIN_PASS_MANAGER_SETUP; event < PLUGIN_EVENT_LAST; event++)
+ for (event = PLUGIN_PASS_MANAGER_SETUP; event < event_last; event++)
if (plugin_callbacks[event])
return true;
@@ -643,7 +765,7 @@ dump_active_plugins (FILE *file)
return;
fprintf (file, FMT_FOR_PLUGIN_EVENT " | %s\n", _("Event"), _("Plugins"));
- for (event = PLUGIN_PASS_MANAGER_SETUP; event < PLUGIN_EVENT_LAST; event++)
+ for (event = PLUGIN_PASS_MANAGER_SETUP; event < event_last; event++)
if (plugin_callbacks[event])
{
struct callback_info *ci;
@@ -688,3 +810,13 @@ plugin_default_version_check (struct plugin_gcc_version *gcc_version,
return false;
return true;
}
+
+/* Return the current value of event_last, so that plugins which provide
+ additional functionality for events for the benefit of high-level plugins
+ know how many valid entries plugin_event_name holds. */
+
+int
+get_event_last (void)
+{
+ return event_last;
+}
diff --git a/gcc/plugin.h b/gcc/plugin.h
index b610b23ed93..1e1dd594937 100644
--- a/gcc/plugin.h
+++ b/gcc/plugin.h
@@ -26,7 +26,7 @@ struct attribute_spec;
extern void add_new_plugin (const char *);
extern void parse_plugin_arg_opt (const char *);
-extern void invoke_plugin_callbacks (enum plugin_event, void *);
+extern int invoke_plugin_callbacks (int, void *);
extern void initialize_plugins (void);
extern bool plugins_active_p (void);
extern void dump_active_plugins (FILE *);
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index ff73c4afb05..75f034376cb 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "diagnostic.h"
#include "cselib.h"
+#include "tree-pass.h"
#endif
static FILE *outfile;
@@ -78,7 +79,7 @@ void
print_mem_expr (FILE *outfile, const_tree expr)
{
fputc (' ', outfile);
- print_generic_expr (outfile, CONST_CAST_TREE (expr), 0);
+ print_generic_expr (outfile, CONST_CAST_TREE (expr), dump_flags);
}
#endif
@@ -241,7 +242,7 @@ print_rtx (const_rtx in_rtx)
{
tree decl = SYMBOL_REF_DECL (in_rtx);
if (decl)
- print_node_brief (outfile, "", decl, 0);
+ print_node_brief (outfile, "", decl, dump_flags);
}
#endif
else if (i == 4 && NOTE_P (in_rtx))
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index a44d23a8474..eebd1c35ba1 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include "diagnostic.h"
#include "tree-flow.h"
+#include "tree-pass.h"
/* Define the hash table of nodes already seen.
Such nodes are not repeated; brief cross-references are used. */
@@ -95,10 +96,22 @@ print_node_brief (FILE *file, const char *prefix, const_tree node, int indent)
fprintf (file, " %s", IDENTIFIER_POINTER (DECL_NAME (node)));
else if (TREE_CODE (node) == LABEL_DECL
&& LABEL_DECL_UID (node) != -1)
- fprintf (file, " L.%d", (int) LABEL_DECL_UID (node));
+ {
+ if (dump_flags & TDF_NOUID)
+ fprintf (file, " L.xxxx");
+ else
+ fprintf (file, " L.%d", (int) LABEL_DECL_UID (node));
+ }
else
- fprintf (file, " %c.%u", TREE_CODE (node) == CONST_DECL ? 'C' : 'D',
- DECL_UID (node));
+ {
+ if (dump_flags & TDF_NOUID)
+ fprintf (file, " %c.xxxx",
+ TREE_CODE (node) == CONST_DECL ? 'C' : 'D');
+ else
+ fprintf (file, " %c.%u",
+ TREE_CODE (node) == CONST_DECL ? 'C' : 'D',
+ DECL_UID (node));
+ }
}
else if (tclass == tcc_type)
{
@@ -260,10 +273,20 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
fprintf (file, " %s", IDENTIFIER_POINTER (DECL_NAME (node)));
else if (code == LABEL_DECL
&& LABEL_DECL_UID (node) != -1)
- fprintf (file, " L.%d", (int) LABEL_DECL_UID (node));
+ {
+ if (dump_flags & TDF_NOUID)
+ fprintf (file, " L.xxxx");
+ else
+ fprintf (file, " L.%d", (int) LABEL_DECL_UID (node));
+ }
else
- fprintf (file, " %c.%u", code == CONST_DECL ? 'C' : 'D',
- DECL_UID (node));
+ {
+ if (dump_flags & TDF_NOUID)
+ fprintf (file, " %c.xxxx", code == CONST_DECL ? 'C' : 'D');
+ else
+ fprintf (file, " %c.%u", code == CONST_DECL ? 'C' : 'D',
+ DECL_UID (node));
+ }
}
else if (tclass == tcc_type)
{
diff --git a/gcc/sese.c b/gcc/sese.c
index 338f482eec1..2c033939b7f 100644
--- a/gcc/sese.c
+++ b/gcc/sese.c
@@ -332,9 +332,6 @@ new_sese (edge entry, edge exit)
SESE_LOOP_NEST (region) = VEC_alloc (loop_p, heap, 3);
SESE_ADD_PARAMS (region) = true;
SESE_PARAMS (region) = VEC_alloc (tree, heap, 3);
- SESE_PARAMS_INDEX (region) = htab_create (10, clast_name_index_elt_info,
- eq_clast_name_indexes, free);
- SESE_PARAMS_NAMES (region) = XNEWVEC (char *, num_ssa_names);
return region;
}
@@ -350,11 +347,6 @@ free_sese (sese region)
VEC_free (tree, heap, SESE_PARAMS (region));
VEC_free (loop_p, heap, SESE_LOOP_NEST (region));
- if (SESE_PARAMS_INDEX (region))
- htab_delete (SESE_PARAMS_INDEX (region));
-
- /* Do not free SESE_PARAMS_NAMES: CLooG does that. */
-
XDELETE (region);
}
diff --git a/gcc/sese.h b/gcc/sese.h
index c126a6964f8..6763db34c27 100644
--- a/gcc/sese.h
+++ b/gcc/sese.h
@@ -32,12 +32,6 @@ typedef struct sese_s
/* Parameters used within the SCOP. */
VEC (tree, heap) *params;
- /* Used to quickly retrieve the index of a parameter in PARAMS. */
- htab_t params_index;
-
- /* Store the names of the parameters that are passed to CLooG. */
- char **params_names;
-
/* Loops completely contained in the SCOP. */
bitmap loops;
VEC (loop_p, heap) *loop_nest;
@@ -53,8 +47,6 @@ typedef struct sese_s
#define SESE_EXIT(S) (S->exit)
#define SESE_EXIT_BB(S) (S->exit->dest)
#define SESE_PARAMS(S) (S->params)
-#define SESE_PARAMS_INDEX(S) (S->params_index)
-#define SESE_PARAMS_NAMES(S) (S->params_names)
#define SESE_LOOPS(S) (S->loops)
#define SESE_LOOP_NEST(S) (S->loop_nest)
#define SESE_ADD_PARAMS(S) (S->add_params)
@@ -222,105 +214,6 @@ block_before_sese (sese sese)
return SESE_ENTRY (sese)->src;
}
-/* Stores the INDEX in a vector for a given clast NAME. */
-
-typedef struct clast_name_index {
- int index;
- const char *name;
-} *clast_name_index_p;
-
-/* Returns a pointer to a new element of type clast_name_index_p built
- from NAME and INDEX. */
-
-static inline clast_name_index_p
-new_clast_name_index (const char *name, int index)
-{
- clast_name_index_p res = XNEW (struct clast_name_index);
-
- res->name = name;
- res->index = index;
- return res;
-}
-
-/* For a given clast NAME, returns -1 if it does not correspond to any
- parameter, or otherwise, returns the index in the PARAMS or
- SCATTERING_DIMENSIONS vector. */
-
-static inline int
-clast_name_to_index (const char *name, htab_t index_table)
-{
- struct clast_name_index tmp;
- PTR *slot;
-
- tmp.name = name;
- slot = htab_find_slot (index_table, &tmp, NO_INSERT);
-
- if (slot && *slot)
- return ((struct clast_name_index *) *slot)->index;
-
- return -1;
-}
-
-/* Records in INDEX_TABLE the INDEX for NAME. */
-
-static inline void
-save_clast_name_index (htab_t index_table, const char *name, int index)
-{
- struct clast_name_index tmp;
- PTR *slot;
-
- tmp.name = name;
- slot = htab_find_slot (index_table, &tmp, INSERT);
-
- if (slot)
- *slot = new_clast_name_index (name, index);
-}
-
-/* Print to stderr the element ELT. */
-
-static inline void
-debug_clast_name_index (clast_name_index_p elt)
-{
- fprintf (stderr, "(index = %d, name = %s)\n", elt->index, elt->name);
-}
-
-/* Helper function for debug_rename_map. */
-
-static inline int
-debug_clast_name_indexes_1 (void **slot, void *s ATTRIBUTE_UNUSED)
-{
- struct clast_name_index *entry = (struct clast_name_index *) *slot;
- debug_clast_name_index (entry);
- return 1;
-}
-
-/* Print to stderr all the elements of MAP. */
-
-static inline void
-debug_clast_name_indexes (htab_t map)
-{
- htab_traverse (map, debug_clast_name_indexes_1, NULL);
-}
-
-/* Computes a hash function for database element ELT. */
-
-static inline hashval_t
-clast_name_index_elt_info (const void *elt)
-{
- return htab_hash_pointer (((const struct clast_name_index *) elt)->name);
-}
-
-/* Compares database elements E1 and E2. */
-
-static inline int
-eq_clast_name_indexes (const void *e1, const void *e2)
-{
- const struct clast_name_index *elt1 = (const struct clast_name_index *) e1;
- const struct clast_name_index *elt2 = (const struct clast_name_index *) e2;
-
- return (elt1->name == elt2->name);
-}
-
/* A single entry single exit specialized for conditions. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5ea107d0a09..2b856c28b8c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,101 @@
+2009-12-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/41611
+ * g++.dg/abi/guard1.C: New.
+
+2009-12-91 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.target/i386/vperm-v4sf-1.c (dg-options): Use -msse.
+
+2009-12-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/42234
+ * g++.dg/gomp/pr42234.C: New test.
+
+2009-12-01 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/42237
+ * gcc.c-torture/compile/pr42237.c: New test.
+
+2009-12-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/42057
+ * g++.dg/parse/crash54.C: New.
+
+2009-11-30 Chao-ying Fu <fu@mips.com>
+
+ * gcc.target/mips/dsp-lhx.c: New test.
+ * gcc.target/mips/dsp-no-lhx.c: New test.
+
+2009-11-30 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * lib/g++.exp (g++_init): Add host-dependent settings for
+ LC_ALL and LANG.
+ * lib/gcc-dg.exp: Likewise.
+ * lib/options.exp: Likewise.
+ * lib/objc.exp (objc_init): Likewise.
+ * lib/gfortran.exp (gfortran_init): Likewise.
+
+2009-11-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/40371
+ * g++.dg/template/crash93.C: New.
+
+2009-11-30 Steve Ellcey <sje@cup.hp.com>
+
+ * gcc.dg/pr41551.c: New test.
+
+2009-11-30 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/42053
+ * gfortran.dg/select_type_9.f03: New.
+
+2009-11-30 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/41631
+ * gfortran.dg/extends_type_of_1.f03: Fix invalid test case.
+ * gfortran.dg/module_md5_1.f90: Adjusted MD5 sum.
+ * gfortran.dg/select_type_1.f03: Remove FIXMEs.
+ * gfortran.dg/select_type_2.f03: Ditto.
+ * gfortran.dg/select_type_8.f03: New test.
+
+2009-11-30 Janus Weil <janus@gcc.gnu.org>
+
+ * gfortran.dg/extends_type_of_1.f03: New test.
+ * gfortran.dg/same_type_as_1.f03: Extended.
+
+2009-11-30 Paul Thomas <pault@gcc.gnu.org>
+
+ * gfortran.dg/class_4c.f03: Add dg-additional-sources.
+ * gfortran.dg/class_4d.f03: Rename module. Cleanup modules.
+
+2009-11-30 Janis Johnson <janis187@us.ibm.com>
+
+ PR testsuite/42212
+ * gcc.target/powerpc/regnames-1.c: Add missing brace dg-do.
+
+2009-11-30 Martin Jambor <mjambor@suse.cz>
+
+ PR middle-end/42196
+ * gcc.c-torture/compile/pr42196-1.c: New test.
+ * gcc.c-torture/compile/pr42196-2.c: New test.
+ * gcc.c-torture/compile/pr42196-3.c: New test.
+
+2009-11-30 Ira Rosen <irar@il.ibm.com>
+
+ * gfortran.dg/vect/vect-7.f90: New test.
+
+2009-11-30 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/42119
+ PR fortran/38530
+ * gfortran.dg/pr42119.f90: New testcase.
+
+2009-11-30 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/42069
+ * g++.dg/template/typedef23.C: New test.
+
2009-11-29 H.J. Lu <hongjiu.lu@intel.com>
PR tree-optimization/41961
diff --git a/gcc/testsuite/g++.dg/abi/guard1.C b/gcc/testsuite/g++.dg/abi/guard1.C
new file mode 100644
index 00000000000..76b43d30f36
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/guard1.C
@@ -0,0 +1,10 @@
+// PR c++/41611
+// { dg-final { scan-assembler-not "_ZGVZN1A1fEvE1i" } }
+
+struct A {
+ static int f()
+ {
+ static int &i = *new int();
+ return i;
+ }
+};
diff --git a/gcc/testsuite/gcc.dg/graphite/pr35356-2.c b/gcc/testsuite/gcc.dg/graphite/pr35356-2.c
index 5432deec61d..e5b0213768c 100644
--- a/gcc/testsuite/gcc.dg/graphite/pr35356-2.c
+++ b/gcc/testsuite/gcc.dg/graphite/pr35356-2.c
@@ -25,8 +25,20 @@ foo (int bar, int n, int k)
| for (i = max(k+1,0); i < n; i++)
| a[i] = i;
+ XXX: At the moment we generate to protect loops that are executed zero times.
+
+ | if (0 < min (n, k) + 1)
+ | for (i = 0; i < min (n, k); i++)
+ | a[i] = i;
+ | if (k >= 0 && k < n)
+ | a[k] = 1;
+ | if (0 < max(n, k) + 1)
+ | for (i = max(k+1,0); i < n; i++)
+ | a[i] = i;
+
*/
-/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "graphite" } } */
-/* { dg-final { scan-tree-dump-times "MAX_EXPR" 1 "graphite" } } */
+
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 2 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "graphite" } } */
/* { dg-final { cleanup-tree-dump "graphite" } } */
diff --git a/gcc/testsuite/gcc.target/i386/vperm-v4sf-1.c b/gcc/testsuite/gcc.target/i386/vperm-v4sf-1.c
index c52c3ab809c..b9fc9b172fe 100644
--- a/gcc/testsuite/gcc.target/i386/vperm-v4sf-1.c
+++ b/gcc/testsuite/gcc.target/i386/vperm-v4sf-1.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O -msse2" } */
+/* { dg-options "-O -msse" } */
#include "isa-check.h"
diff --git a/gcc/testsuite/gcc.target/powerpc/regnames-1.c b/gcc/testsuite/gcc.target/powerpc/regnames-1.c
index c814083c6e3..e34e6241daa 100644
--- a/gcc/testsuite/gcc.target/powerpc/regnames-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/regnames-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target powerpc*-*-linux* } */
+/* { dg-do compile { target powerpc*-*-linux* } } */
/* { dg-options "-mregnames" } */
register double f17 asm ("f17");
diff --git a/gcc/testsuite/gfortran.dg/class_4c.f03 b/gcc/testsuite/gfortran.dg/class_4c.f03
index 7909c0eeda0..c76b3ab6953 100644
--- a/gcc/testsuite/gfortran.dg/class_4c.f03
+++ b/gcc/testsuite/gfortran.dg/class_4c.f03
@@ -1,4 +1,5 @@
! { dg-do run }
+! { dg-additional-sources class_4a.f03 class_4b.f03 }
!
! Test the fix for PR41583, in which the different source files
! would generate the same 'vindex' for different class declared
diff --git a/gcc/testsuite/gfortran.dg/class_4d.f03 b/gcc/testsuite/gfortran.dg/class_4d.f03
index 7a962aa01b9..80934b6c125 100644
--- a/gcc/testsuite/gfortran.dg/class_4d.f03
+++ b/gcc/testsuite/gfortran.dg/class_4d.f03
@@ -8,8 +8,8 @@
!
! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
!
-module m
+module m3
type t
end type t
-end module m
-! { dg-final { cleanup-modules "m m2" } }
+end module m3
+! { dg-final { cleanup-modules "m m2 m3" } }
diff --git a/gcc/testsuite/gfortran.dg/module_md5_1.f90 b/gcc/testsuite/gfortran.dg/module_md5_1.f90
index 88002c204bf..e725b4b767e 100644
--- a/gcc/testsuite/gfortran.dg/module_md5_1.f90
+++ b/gcc/testsuite/gfortran.dg/module_md5_1.f90
@@ -10,5 +10,5 @@ program test
use foo
print *, pi
end program test
-! { dg-final { scan-module "foo" "MD5:9c43cf4d713824ec6894b83250720e68" } }
+! { dg-final { scan-module "foo" "MD5:5632bcd379cf023bf7e663e91d52fa12" } }
! { dg-final { cleanup-modules "foo" } }
diff --git a/gcc/testsuite/gfortran.dg/same_type_as_1.f03 b/gcc/testsuite/gfortran.dg/same_type_as_1.f03
index ba13a0b731e..45b5d26627f 100644
--- a/gcc/testsuite/gfortran.dg/same_type_as_1.f03
+++ b/gcc/testsuite/gfortran.dg/same_type_as_1.f03
@@ -1,6 +1,6 @@
! { dg-do compile }
!
-! Error checking for the intrinsic function SAME_TYPE_AS.
+! Error checking for the intrinsic functions SAME_TYPE_AS and EXTENDS_TYPE_OF.
!
! Contributed by Janus Weil <janus@gcc.gnu.org>
@@ -18,7 +18,10 @@
integer :: i
- print *, SAME_TYPE_AS (l,x1) ! { dg-error "must be of a derived type" }
+ print *, SAME_TYPE_AS (i,x1) ! { dg-error "must be of a derived type" }
print *, SAME_TYPE_AS (x1,x2) ! { dg-error "must be of an extensible type" }
+ print *, EXTENDS_TYPE_OF (i,x1) ! { dg-error "must be of a derived type" }
+ print *, EXTENDS_TYPE_OF (x1,x2) ! { dg-error "must be of an extensible type" }
+
end
diff --git a/gcc/testsuite/gfortran.dg/select_type_1.f03 b/gcc/testsuite/gfortran.dg/select_type_1.f03
index 6a7db2e8954..0214c51a04f 100644
--- a/gcc/testsuite/gfortran.dg/select_type_1.f03
+++ b/gcc/testsuite/gfortran.dg/select_type_1.f03
@@ -40,16 +40,14 @@
print *,"a is TYPE(t1)"
type is (t2)
print *,"a is TYPE(t2)"
-! FIXME: CLASS IS specification is not yet supported
-! class is (ts) ! { FIXME: error "must be extensible" }
-! print *,"a is TYPE(ts)"
+ class is (ts) ! { dg-error "must be extensible" }
+ print *,"a is TYPE(ts)"
type is (t3) ! { dg-error "must be an extension of" }
print *,"a is TYPE(t3)"
type is (t4) ! { dg-error "is not an accessible derived type" }
print *,"a is TYPE(t3)"
-! FIXME: CLASS IS specification is not yet supported
-! class is (t1)
-! print *,"a is CLASS(t1)"
+ class is (t1)
+ print *,"a is CLASS(t1)"
class is (t2) label ! { dg-error "Syntax error" }
print *,"a is CLASS(t2)"
class default ! { dg-error "cannot be followed by a second DEFAULT CASE" }
diff --git a/gcc/testsuite/gfortran.dg/select_type_2.f03 b/gcc/testsuite/gfortran.dg/select_type_2.f03
index 08ac9fef6e8..d4a5343d7b2 100644
--- a/gcc/testsuite/gfortran.dg/select_type_2.f03
+++ b/gcc/testsuite/gfortran.dg/select_type_2.f03
@@ -30,9 +30,8 @@
i = 1
type is (t2)
i = 2
-! FIXME: CLASS IS is not yet supported
-! class is (t1)
-! i = 3
+ class is (t1)
+ i = 3
end select
if (i /= 1) call abort()
@@ -45,9 +44,8 @@
i = 1
type is (t2)
i = 2
-! FIXME: CLASS IS is not yet supported
-! class is (t2)
-! i = 3
+ class is (t2)
+ i = 3
end select
if (i /= 2) call abort()
diff --git a/gcc/testsuite/lib/g++.exp b/gcc/testsuite/lib/g++.exp
index a5f26800c1c..df6030b568c 100644
--- a/gcc/testsuite/lib/g++.exp
+++ b/gcc/testsuite/lib/g++.exp
@@ -193,6 +193,13 @@ proc g++_init { args } {
setenv LC_ALL C
setenv LANG C
+ # Many hosts now default to a non-ASCII C locale, however, so
+ # they can set a charset encoding here if they need.
+ if { [ishost "*-*-cygwin*"] } {
+ setenv LC_ALL C.ASCII
+ setenv LANG C.ASCII
+ }
+
if ![info exists GXX_UNDER_TEST] then {
if [info exists TOOL_EXECUTABLE] {
set GXX_UNDER_TEST $TOOL_EXECUTABLE
diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
index 4acfdfec8ff..512144a6aa6 100644
--- a/gcc/testsuite/lib/gcc-dg.exp
+++ b/gcc/testsuite/lib/gcc-dg.exp
@@ -34,6 +34,13 @@ load_lib torture-options.exp
setenv LC_ALL C
setenv LANG C
+# Many hosts now default to a non-ASCII C locale, however, so
+# they can set a charset encoding here if they need.
+if { [ishost "*-*-cygwin*"] } {
+ setenv LC_ALL C.ASCII
+ setenv LANG C.ASCII
+}
+
if [info exists TORTURE_OPTIONS] {
set DG_TORTURE_OPTIONS $TORTURE_OPTIONS
} else {
diff --git a/gcc/testsuite/lib/gfortran.exp b/gcc/testsuite/lib/gfortran.exp
index a4d6e2b5d38..56aef298776 100644
--- a/gcc/testsuite/lib/gfortran.exp
+++ b/gcc/testsuite/lib/gfortran.exp
@@ -136,6 +136,13 @@ proc gfortran_init { args } {
setenv LC_ALL C
setenv LANG C
+ # Many hosts now default to a non-ASCII C locale, however, so
+ # they can set a charset encoding here if they need.
+ if { [ishost "*-*-cygwin*"] } {
+ setenv LC_ALL C.ASCII
+ setenv LANG C.ASCII
+ }
+
if ![info exists GFORTRAN_UNDER_TEST] then {
if [info exists TOOL_EXECUTABLE] {
set GFORTRAN_UNDER_TEST $TOOL_EXECUTABLE
diff --git a/gcc/testsuite/lib/objc.exp b/gcc/testsuite/lib/objc.exp
index 934f31dabdc..9d7bac0b03b 100644
--- a/gcc/testsuite/lib/objc.exp
+++ b/gcc/testsuite/lib/objc.exp
@@ -102,6 +102,13 @@ proc objc_init { args } {
setenv LC_ALL C
setenv LANG C
+ # Many hosts now default to a non-ASCII C locale, however, so
+ # they can set a charset encoding here if they need.
+ if { [ishost "*-*-cygwin*"] } {
+ setenv LC_ALL C.ASCII
+ setenv LANG C.ASCII
+ }
+
if { $objc_initialized == 1 } { return; }
if ![info exists OBJC_UNDER_TEST] then {
diff --git a/gcc/testsuite/lib/options.exp b/gcc/testsuite/lib/options.exp
index 18359023228..ab4819343f7 100644
--- a/gcc/testsuite/lib/options.exp
+++ b/gcc/testsuite/lib/options.exp
@@ -18,6 +18,13 @@
setenv LC_ALL C
setenv LANG C
+# Many hosts now default to a non-ASCII C locale, however, so
+# they can set a charset encoding here if they need.
+if { [ishost "*-*-cygwin*"] } {
+ setenv LC_ALL C.ASCII
+ setenv LANG C.ASCII
+}
+
# Run the LANGUAGE compiler with GCC_OPTIONS and inspect the compiler
# output to make sure that they match the newline-separated patterns
# in COMPILER_PATTERNS but not the patterns in COMPILER_NON_PATTERNS.
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index 495450bf12c..9fb489a743d 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -1,5 +1,5 @@
/* CFG cleanup for trees.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GCC.
@@ -511,7 +511,7 @@ cleanup_omp_return (basic_block bb)
control_bb = single_pred (bb);
stmt = last_stmt (control_bb);
- if (gimple_code (stmt) != GIMPLE_OMP_SECTIONS_SWITCH)
+ if (stmt == NULL || gimple_code (stmt) != GIMPLE_OMP_SECTIONS_SWITCH)
return false;
/* The block with the control statement normally has two entry edges -- one
diff --git a/gcc/tree-dump.c b/gcc/tree-dump.c
index e0512bc80a3..429f915bcc9 100644
--- a/gcc/tree-dump.c
+++ b/gcc/tree-dump.c
@@ -821,6 +821,7 @@ static const struct dump_option_value_info dump_options[] =
{"memsyms", TDF_MEMSYMS},
{"verbose", TDF_VERBOSE},
{"eh", TDF_EH},
+ {"nouid", TDF_NOUID},
{"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA
| TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE
| TDF_RHS_ONLY)},
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 10baf62b0c0..3c909419bd2 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1093,10 +1093,10 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
/* If EXPR has block defined, map it to newly constructed block.
When inlining we want EXPRs without block appear in the block
- of function call. */
+ of function call if we are not remapping a type. */
if (EXPR_P (*tp))
{
- new_block = id->block;
+ new_block = id->remapping_type_depth == 0 ? id->block : NULL;
if (TREE_BLOCK (*tp))
{
tree *n;
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index d6f659c0624..243fe770e17 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -1151,27 +1151,43 @@ static void
insert_phi_nodes (bitmap *dfs)
{
referenced_var_iterator rvi;
+ bitmap_iterator bi;
tree var;
+ bitmap vars;
+ unsigned uid;
timevar_push (TV_TREE_INSERT_PHI_NODES);
+ /* Do two stages to avoid code generation differences for UID
+ differences but no UID ordering differences. */
+
+ vars = BITMAP_ALLOC (NULL);
FOR_EACH_REFERENCED_VAR (var, rvi)
{
struct def_blocks_d *def_map;
- bitmap idf;
def_map = find_def_blocks_for (var);
if (def_map == NULL)
continue;
if (get_phi_state (var) != NEED_PHI_STATE_NO)
- {
- idf = compute_idf (def_map->def_blocks, dfs);
- insert_phi_nodes_for (var, idf, false);
- BITMAP_FREE (idf);
- }
+ bitmap_set_bit (vars, DECL_UID (var));
}
+ EXECUTE_IF_SET_IN_BITMAP (vars, 0, uid, bi)
+ {
+ tree var = referenced_var (uid);
+ struct def_blocks_d *def_map;
+ bitmap idf;
+
+ def_map = find_def_blocks_for (var);
+ idf = compute_idf (def_map->def_blocks, dfs);
+ insert_phi_nodes_for (var, idf, false);
+ BITMAP_FREE (idf);
+ }
+
+ BITMAP_FREE (vars);
+
timevar_pop (TV_TREE_INSERT_PHI_NODES);
}
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c
index 23b7046c60d..42e7d10b128 100644
--- a/gcc/tree-optimize.c
+++ b/gcc/tree-optimize.c
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
#include "graph.h"
#include "cfgloop.h"
#include "except.h"
+#include "plugin.h"
/* Gate: execute, or not, all of the non-trivial optimizations. */
@@ -405,8 +406,15 @@ tree_rest_of_compilation (tree fndecl)
execute_all_ipa_transforms ();
/* Perform all tree transforms and optimizations. */
+
+ /* Signal the start of passes. */
+ invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
+
execute_pass_list (all_passes);
+ /* Signal the end of passes. */
+ invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
+
bitmap_obstack_release (&reg_obstack);
/* Release the default bitmap obstack. */
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 1bff0bd52ce..b997eb126ec 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -79,6 +79,7 @@ enum tree_dump_index
#define TDF_EH (1 << 19) /* display EH region number
holding this gimple statement. */
+#define TDF_NOUID (1 << 20) /* omit UIDs from dumps. */
/* In tree-dump.c */
@@ -565,12 +566,16 @@ extern struct opt_pass *all_passes, *all_small_ipa_passes, *all_lowering_passes,
extern struct opt_pass *current_pass;
extern struct opt_pass * get_pass_for_id (int);
+extern bool execute_one_pass (struct opt_pass *);
extern void execute_pass_list (struct opt_pass *);
extern void execute_ipa_pass_list (struct opt_pass *);
extern void execute_ipa_summary_passes (struct ipa_opt_pass_d *);
extern void execute_all_ipa_transforms (void);
extern void execute_all_ipa_stmt_fixups (struct cgraph_node *, gimple *);
+extern bool pass_init_dump_file (struct opt_pass *);
+extern void pass_fini_dump_file (struct opt_pass *);
+extern const char *get_current_pass_name (void);
extern void print_current_pass (FILE *);
extern void debug_pass (void);
extern void ipa_write_summaries (void);
@@ -590,4 +595,7 @@ extern void register_pass (struct register_pass_info *);
directly in jump threading, and avoid peeling them next time. */
extern bool first_pass_instance;
+/* Declare for plugins. */
+extern void do_per_function_toporder (void (*) (void *), void *);
+
#endif /* GCC_TREE_PASS_H */
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index caa19ac8d6c..44d4a5d9c03 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -182,13 +182,21 @@ dump_decl_name (pretty_printer *buffer, tree node, int flags)
if ((flags & TDF_UID) || DECL_NAME (node) == NULL_TREE)
{
if (TREE_CODE (node) == LABEL_DECL && LABEL_DECL_UID (node) != -1)
- pp_printf (buffer, "L.%d", (int) LABEL_DECL_UID (node));
+ pp_printf (buffer, "L.%d", (int) LABEL_DECL_UID (node));
else if (TREE_CODE (node) == DEBUG_EXPR_DECL)
- pp_printf (buffer, "D#%i", DEBUG_TEMP_UID (node));
+ {
+ if (flags & TDF_NOUID)
+ pp_string (buffer, "D#xxxx");
+ else
+ pp_printf (buffer, "D#%i", DEBUG_TEMP_UID (node));
+ }
else
{
char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
- pp_printf (buffer, "%c.%u", c, DECL_UID (node));
+ if (flags & TDF_NOUID)
+ pp_printf (buffer, "%c.xxxx", c);
+ else
+ pp_printf (buffer, "%c.%u", c, DECL_UID (node));
}
}
}
@@ -1030,9 +1038,14 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
if (DECL_NAME (node))
dump_decl_name (buffer, node, flags);
else if (LABEL_DECL_UID (node) != -1)
- pp_printf (buffer, "<L%d>", (int) LABEL_DECL_UID (node));
+ pp_printf (buffer, "<L%d>", (int) LABEL_DECL_UID (node));
else
- pp_printf (buffer, "<D.%u>", DECL_UID (node));
+ {
+ if (flags & TDF_NOUID)
+ pp_string (buffer, "<D.xxxx>");
+ else
+ pp_printf (buffer, "<D.%u>", DECL_UID (node));
+ }
break;
case TYPE_DECL:
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 34c0d3de893..a6a1a90d757 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -199,6 +199,10 @@ struct access
BIT_FIELD_REF? */
unsigned grp_partial_lhs : 1;
+ /* Does this group contain accesses to different types? (I.e. through a union
+ or a similar mechanism). */
+ unsigned grp_different_types : 1;
+
/* Set when a scalar replacement should be created for this variable. We do
the decision and creation at different places because create_tmp_var
cannot be called from within FOR_EACH_REFERENCED_VAR. */
@@ -339,12 +343,14 @@ dump_access (FILE *f, struct access *access, bool grp)
fprintf (f, ", grp_write = %d, grp_read = %d, grp_hint = %d, "
"grp_covered = %d, grp_unscalarizable_region = %d, "
"grp_unscalarized_data = %d, grp_partial_lhs = %d, "
- "grp_to_be_replaced = %d\n grp_maybe_modified = %d, "
+ "grp_different_types = %d, grp_to_be_replaced = %d, "
+ "grp_maybe_modified = %d, "
"grp_not_necessarilly_dereferenced = %d\n",
access->grp_write, access->grp_read, access->grp_hint,
access->grp_covered, access->grp_unscalarizable_region,
access->grp_unscalarized_data, access->grp_partial_lhs,
- access->grp_to_be_replaced, access->grp_maybe_modified,
+ access->grp_different_types, access->grp_to_be_replaced,
+ access->grp_maybe_modified,
access->grp_not_necessarilly_dereferenced);
else
fprintf (f, ", write = %d, grp_partial_lhs = %d\n", access->write,
@@ -1112,14 +1118,25 @@ compare_access_positions (const void *a, const void *b)
{
/* Put any non-aggregate type before any aggregate type. */
if (!is_gimple_reg_type (f1->type)
- && is_gimple_reg_type (f2->type))
+ && is_gimple_reg_type (f2->type))
return 1;
else if (is_gimple_reg_type (f1->type)
&& !is_gimple_reg_type (f2->type))
return -1;
+ /* Put any complex or vector type before any other scalar type. */
+ else if (TREE_CODE (f1->type) != COMPLEX_TYPE
+ && TREE_CODE (f1->type) != VECTOR_TYPE
+ && (TREE_CODE (f2->type) == COMPLEX_TYPE
+ || TREE_CODE (f2->type) == VECTOR_TYPE))
+ return 1;
+ else if ((TREE_CODE (f1->type) == COMPLEX_TYPE
+ || TREE_CODE (f1->type) == VECTOR_TYPE)
+ && TREE_CODE (f2->type) != COMPLEX_TYPE
+ && TREE_CODE (f2->type) != VECTOR_TYPE)
+ return -1;
/* Put the integral type with the bigger precision first. */
else if (INTEGRAL_TYPE_P (f1->type)
- && INTEGRAL_TYPE_P (f2->type))
+ && INTEGRAL_TYPE_P (f2->type))
return TYPE_PRECISION (f1->type) > TYPE_PRECISION (f2->type) ? -1 : 1;
/* Put any integral type with non-full precision last. */
else if (INTEGRAL_TYPE_P (f1->type)
@@ -1417,6 +1434,7 @@ sort_and_splice_var_accesses (tree var)
bool grp_read = !access->write;
bool multiple_reads = false;
bool grp_partial_lhs = access->grp_partial_lhs;
+ bool grp_different_types = false;
bool first_scalar = is_gimple_reg_type (access->type);
bool unscalarizable_region = access->grp_unscalarizable_region;
@@ -1448,6 +1466,7 @@ sort_and_splice_var_accesses (tree var)
grp_read = true;
}
grp_partial_lhs |= ac2->grp_partial_lhs;
+ grp_different_types |= !types_compatible_p (access->type, ac2->type);
unscalarizable_region |= ac2->grp_unscalarizable_region;
relink_to_new_repr (access, ac2);
@@ -1466,6 +1485,7 @@ sort_and_splice_var_accesses (tree var)
access->grp_read = grp_read;
access->grp_hint = multiple_reads;
access->grp_partial_lhs = grp_partial_lhs;
+ access->grp_different_types = grp_different_types;
access->grp_unscalarizable_region = unscalarizable_region;
if (access->first_link)
add_access_to_work_queue (access);
@@ -2112,8 +2132,15 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write,
access expression to extract the scalar component afterwards.
This happens if scalarizing a function return value or parameter
like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
- gcc.c-torture/compile/20011217-1.c. */
- if (!is_gimple_reg_type (type))
+ gcc.c-torture/compile/20011217-1.c.
+
+ We also want to use this when accessing a complex or vector which can
+ be accessed as a different type too, potentially creating a need for
+ type conversion (see PR42196). */
+ if (!is_gimple_reg_type (type)
+ || (access->grp_different_types
+ && (TREE_CODE (type) == COMPLEX_TYPE
+ || TREE_CODE (type) == VECTOR_TYPE)))
{
tree ref = access->base;
bool ok;
@@ -3680,12 +3707,22 @@ sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi, void *data)
any |= sra_ipa_modify_expr (lhs_p, gsi, true, data);
if (any)
{
+ tree new_rhs = NULL_TREE;
+
if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
+ new_rhs = fold_build1_loc (gimple_location (stmt), VIEW_CONVERT_EXPR,
+ TREE_TYPE (*lhs_p), *rhs_p);
+ else if (REFERENCE_CLASS_P (*rhs_p)
+ && is_gimple_reg_type (TREE_TYPE (*lhs_p))
+ && !is_gimple_reg (*lhs_p))
+ /* This can happen when an assignment in between two single field
+ structures is turned into an assignment in between two pointers to
+ scalars (PR 42237). */
+ new_rhs = *rhs_p;
+
+ if (new_rhs)
{
- location_t loc = gimple_location (stmt);
- tree vce = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
- TREE_TYPE (*lhs_p), *rhs_p);
- tree tmp = force_gimple_operand_gsi (gsi, vce, true, NULL_TREE,
+ tree tmp = force_gimple_operand_gsi (gsi, new_rhs, true, NULL_TREE,
true, GSI_SAME_STMT);
gimple_assign_set_rhs_from_tree (gsi, tmp);
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index d75edb5a061..c0ccb4fe20d 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -475,11 +475,7 @@ remove_unused_scope_block_p (tree scope)
type is used or not. */
else if (debug_info_level == DINFO_LEVEL_NORMAL
- || debug_info_level == DINFO_LEVEL_VERBOSE
- /* Removing declarations before inlining is going to affect
- DECL_UID that in turn is going to affect hashtables and
- code generation. */
- || !cfun->after_inlining)
+ || debug_info_level == DINFO_LEVEL_VERBOSE)
;
else
{
@@ -527,12 +523,6 @@ remove_unused_scope_block_p (tree scope)
eliminated. */
else if (!nsubblocks)
;
- /* If there are live subblocks and we still have some unused variables
- or types declared, we must keep them.
- Before inliing we must not depend on debug info verbosity to keep
- DECL_UIDs stable. */
- else if (!cfun->after_inlining && BLOCK_VARS (scope))
- unused = false;
/* For terse debug info we can eliminate info on unused variables. */
else if (debug_info_level == DINFO_LEVEL_NONE
|| debug_info_level == DINFO_LEVEL_TERSE)
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 7ce91cadb34..99230909d7d 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -1809,10 +1809,12 @@ vectorizable_assignment (gimple stmt, gimple_stmt_iterator *gsi,
enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies;
- int i;
+ int i, j;
VEC(tree,heap) *vec_oprnds = NULL;
tree vop;
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
+ gimple new_stmt = NULL;
+ stmt_vec_info prev_stmt_info = NULL;
/* Multiple types in SLP are handled by creating the appropriate number of
vectorized stmts for each SLP node. Hence, NCOPIES is always 1 in
@@ -1823,8 +1825,6 @@ vectorizable_assignment (gimple stmt, gimple_stmt_iterator *gsi,
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
gcc_assert (ncopies >= 1);
- if (ncopies > 1)
- return false; /* FORNOW */
if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
return false;
@@ -1870,20 +1870,35 @@ vectorizable_assignment (gimple stmt, gimple_stmt_iterator *gsi,
vec_dest = vect_create_destination_var (scalar_dest, vectype);
/* Handle use. */
- vect_get_vec_defs (op, NULL, stmt, &vec_oprnds, NULL, slp_node);
-
- /* Arguments are ready. create the new vector stmt. */
- for (i = 0; VEC_iterate (tree, vec_oprnds, i, vop); i++)
+ for (j = 0; j < ncopies; j++)
{
- *vec_stmt = gimple_build_assign (vec_dest, vop);
- new_temp = make_ssa_name (vec_dest, *vec_stmt);
- gimple_assign_set_lhs (*vec_stmt, new_temp);
- vect_finish_stmt_generation (stmt, *vec_stmt, gsi);
- STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt;
+ /* Handle uses. */
+ if (j == 0)
+ vect_get_vec_defs (op, NULL, stmt, &vec_oprnds, NULL, slp_node);
+ else
+ vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds, NULL);
+
+ /* Arguments are ready. create the new vector stmt. */
+ for (i = 0; VEC_iterate (tree, vec_oprnds, i, vop); i++)
+ {
+ new_stmt = gimple_build_assign (vec_dest, vop);
+ new_temp = make_ssa_name (vec_dest, new_stmt);
+ gimple_assign_set_lhs (new_stmt, new_temp);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ if (slp_node)
+ VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
+ }
if (slp_node)
- VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), *vec_stmt);
- }
+ continue;
+
+ if (j == 0)
+ STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
+ else
+ STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
+
+ prev_stmt_info = vinfo_for_stmt (new_stmt);
+ }
VEC_free (tree, heap, vec_oprnds);
return true;
diff --git a/gcc/tree.c b/gcc/tree.c
index dc4820981ed..f8fb6ce8770 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -4934,7 +4934,7 @@ free_lang_data (void)
/* FIXME. Remove after save_debug_info is working. */
if (!(flag_generate_lto
- || (!flag_gtoggle && debug_info_level <= DINFO_LEVEL_TERSE)))
+ || (!flag_gtoggle && debug_info_level == DINFO_LEVEL_NONE)))
return 0;
/* Traverse the IL resetting language specific information for
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index 651a01e0b6e..c0adaa9226b 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,3 +1,32 @@
+2009-11-30 David Edelsohn <edelsohn@gnu.org>
+
+ * src/powerpc/aix.S (ffi_call_AIX): Convert to more standard
+ register usage. Call ffi_prep_args directly. Add long double
+ return value support.
+ * src/powerpc/ffi_darwin.c (ffi_prep_args): Double arg increment
+ applies to FFI_TYPE_DOUBLE. Correct fpr_base increment typo.
+ Separate FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases.
+ (ffi_prep_cif_machdep): Only 16 byte stack alignment in 64 bit
+ mode.
+ (ffi_closure_helper_DARWIN): Remove nf and ng counters. Move temp
+ into case.
+ * src/powerpc/aix_closure.S: Maintain 16 byte stack alignment.
+ Allocate result area between params and FPRs.
+
+2009-11-30 David Edelsohn <edelsohn@gnu.org>
+
+ PR target/35484
+ * src/powerpc/ffitarget.h (POWERPC64): Define for PPC64 Linux and
+ AIX64.
+ * src/powerpc/aix.S: Implement AIX64 version.
+ * src/powerpc/aix_closure.S: Implement AIX64 version.
+ (ffi_closure_ASM): Use extsb, lha and displament addresses.
+ * src/powerpc/ffi_darwin.c (ffi_prep_args): Implement AIX64
+ support.
+ (ffi_prep_cif_machdep): Same.
+ (ffi_call): Same.
+ (ffi_closure_helper_DARWIN): Same.
+
2009-11-02 Andreas Tobler <a.tobler@schweiz.org>
PR libffi/41908
diff --git a/libffi/src/powerpc/aix.S b/libffi/src/powerpc/aix.S
index 45502f7963e..5b477cad5e8 100644
--- a/libffi/src/powerpc/aix.S
+++ b/libffi/src/powerpc/aix.S
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- aix.S - Copyright (c) 2002 Free Software Foundation, Inc.
+ aix.S - Copyright (c) 2002,2009 Free Software Foundation, Inc.
based on darwin.S by John Hornkvist
PowerPC Assembly glue.
@@ -86,9 +86,13 @@
#define L(x) x
.file "aix.S"
.toc
- .csect .text[PR]
- .align 2
-.globl ffi_prep_args
+
+ /* void ffi_call_AIX(extended_cif *ecif, unsigned long bytes,
+ * unsigned int flags, unsigned int *rvalue,
+ * void (*fn)(),
+ * void (*prep_args)(extended_cif*, unsigned *const));
+ * r3=ecif, r4=bytes, r5=flags, r6=rvalue, r7=fn, r8=prep_args
+ */
.csect .text[PR]
.align 2
@@ -96,10 +100,111 @@
.globl .ffi_call_AIX
.csect ffi_call_AIX[DS]
ffi_call_AIX:
+#ifdef __64BIT__
+ .llong .ffi_call_AIX, TOC[tc0], 0
+ .csect .text[PR]
+.ffi_call_AIX:
+ /* Save registers we use. */
+ mflr r0
+
+ std r28,-32(r1)
+ std r29,-24(r1)
+ std r30,-16(r1)
+ std r31, -8(r1)
+
+ std r0, 16(r1)
+ mr r28, r1 /* our AP. */
+ stdux r1, r1, r4
+
+ /* Save arguments over call... */
+ mr r31, r5 /* flags, */
+ mr r30, r6 /* rvalue, */
+ mr r29, r7 /* function address. */
+ std r2, 40(r1)
+
+ /* Call ffi_prep_args. */
+ mr r4, r1
+ bl .ffi_prep_args
+
+ /* Now do the call. */
+ ld r0, 0(r29)
+ ld r2, 8(r29)
+ /* Set up cr1 with bits 4-7 of the flags. */
+ mtcrf 0x40, r31
+ mtctr r0
+ /* Load all those argument registers. */
+ // We have set up a nice stack frame, just load it into registers.
+ ld r3, 40+(1*8)(r1)
+ ld r4, 40+(2*8)(r1)
+ ld r5, 40+(3*8)(r1)
+ ld r6, 40+(4*8)(r1)
+ nop
+ ld r7, 40+(5*8)(r1)
+ ld r8, 40+(6*8)(r1)
+ ld r9, 40+(7*8)(r1)
+ ld r10,40+(8*8)(r1)
+
+L1:
+ /* Load all the FP registers. */
+ bf 6,L2 // 2f + 0x18
+ lfd f1,-32-(13*8)(r28)
+ lfd f2,-32-(12*8)(r28)
+ lfd f3,-32-(11*8)(r28)
+ lfd f4,-32-(10*8)(r28)
+ nop
+ lfd f5,-32-(9*8)(r28)
+ lfd f6,-32-(8*8)(r28)
+ lfd f7,-32-(7*8)(r28)
+ lfd f8,-32-(6*8)(r28)
+ nop
+ lfd f9,-32-(5*8)(r28)
+ lfd f10,-32-(4*8)(r28)
+ lfd f11,-32-(3*8)(r28)
+ lfd f12,-32-(2*8)(r28)
+ nop
+ lfd f13,-32-(1*8)(r28)
+
+L2:
+ /* Make the call. */
+ bctrl
+ ld r2, 40(r1)
+
+ /* Now, deal with the return value. */
+ mtcrf 0x01, r31
+
+ bt 30, L(done_return_value)
+ bt 29, L(fp_return_value)
+ std r3, 0(r30)
+
+ /* Fall through... */
+
+L(done_return_value):
+ /* Restore the registers we used and return. */
+ mr r1, r28
+ ld r0, 16(r28)
+ ld r28,-32(r1)
+ mtlr r0
+ ld r29,-24(r1)
+ ld r30,-16(r1)
+ ld r31,-8(r1)
+ blr
+
+L(fp_return_value):
+ bf 28,L(float_return_value)
+ stfd f1,0(r30)
+ bf 31,L(done_return_value)
+ stfd f2,8(r30)
+ b L(done_return_value)
+L(float_return_value):
+ stfs f1,0(r30)
+ b L(done_return_value)
+
+#else /* ! __64BIT__ */
+
.long .ffi_call_AIX, TOC[tc0], 0
.csect .text[PR]
.ffi_call_AIX:
- mr r12,r8 // We only need r12 until the call, so it doesn't have to be saved...
+ mr r12,r8 // We only need r12 until the call, so it doesn't have to be saved...
/* Save the old stack pointer as AP. */
mr r8,r1
@@ -142,15 +247,15 @@ ffi_call_AIX:
lwz r2,4(r29)
/* Load all those argument registers. */
// We have set up a nice stack frame, just load it into registers.
- lwz r3, 20+(1*4)(r1)
- lwz r4, 20+(2*4)(r1)
- lwz r5, 20+(3*4)(r1)
- lwz r6, 20+(4*4)(r1)
+ lwz r3, 20+(1*4)(r1)
+ lwz r4, 20+(2*4)(r1)
+ lwz r5, 20+(3*4)(r1)
+ lwz r6, 20+(4*4)(r1)
nop
- lwz r7, 20+(5*4)(r1)
- lwz r8, 20+(6*4)(r1)
- lwz r9, 20+(7*4)(r1)
- lwz r10,20+(8*4)(r1)
+ lwz r7, 20+(5*4)(r1)
+ lwz r8, 20+(6*4)(r1)
+ lwz r9, 20+(7*4)(r1)
+ lwz r10,20+(8*4)(r1)
L1:
/* Load all the FP registers. */
@@ -165,17 +270,17 @@ L1:
lfd f7,-16-(7*8)(r28)
lfd f8,-16-(6*8)(r28)
nop
- lfd f9,-16-(5*8)(r28)
- lfd f10,-16-(4*8)(r28)
- lfd f11,-16-(3*8)(r28)
- lfd f12,-16-(2*8)(r28)
+ lfd f9,-16-(5*8)(r28)
+ lfd f10,-16-(4*8)(r28)
+ lfd f11,-16-(3*8)(r28)
+ lfd f12,-16-(2*8)(r28)
nop
- lfd f13,-16-(1*8)(r28)
+ lfd f13,-16-(1*8)(r28)
L2:
/* Make the call. */
bctrl
- lwz r2,20(r1)
+ lwz r2,20(r1)
/* Now, deal with the return value. */
mtcrf 0x01,r31
@@ -190,8 +295,8 @@ L2:
L(done_return_value):
/* Restore the registers we used and return. */
- lwz r9, 8(r28)
- lwz r31, -4(r28)
+ lwz r9,8(r28)
+ lwz r31,-4(r28)
mtlr r9
lwz r30, -8(r28)
lwz r29,-12(r28)
@@ -206,6 +311,7 @@ L(fp_return_value):
L(float_return_value):
stfs f1,0(r30)
b L(done_return_value)
+#endif
.long 0
.byte 0,0,0,1,128,4,0,0
//END(ffi_call_AIX)
@@ -216,7 +322,11 @@ L(float_return_value):
.globl .ffi_call_DARWIN
.csect ffi_call_DARWIN[DS]
ffi_call_DARWIN:
+#ifdef __64BIT__
+ .llong .ffi_call_DARWIN, TOC[tc0], 0
+#else
.long .ffi_call_DARWIN, TOC[tc0], 0
+#endif
.csect .text[PR]
.ffi_call_DARWIN:
blr
diff --git a/libffi/src/powerpc/aix_closure.S b/libffi/src/powerpc/aix_closure.S
index 7bf5c656063..70456188092 100644
--- a/libffi/src/powerpc/aix_closure.S
+++ b/libffi/src/powerpc/aix_closure.S
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- aix_closure.S - Copyright (c) 2002 2003 Free Software Foundation, Inc.
+ aix_closure.S - Copyright (c) 2002, 2003, 2009 Free Software Foundation, Inc.
based on darwin_closure.S
PowerPC Assembly glue.
@@ -94,8 +94,163 @@ LC..60:
.globl ffi_closure_ASM
.globl .ffi_closure_ASM
.csect ffi_closure_ASM[DS]
-
ffi_closure_ASM:
+#ifdef __64BIT__
+ .llong .ffi_closure_ASM, TOC[tc0], 0
+ .csect .text[PR]
+.ffi_closure_ASM:
+
+ mflr r0 /* extract return address */
+ std r0,16(r1) /* save the return address */
+
+ /* 48 Bytes (Linkage Area) */
+ /* 64 Bytes (params) */
+ /* 16 Bytes (result) */
+ /* 104 Bytes (13*8 from FPR) */
+ /* 8 Bytes (alignment) */
+ /* 240 Bytes */
+
+ stdu r1,-240(r1) /* skip over caller save area
+ keep stack aligned to 16 */
+
+/* we want to build up an area for the parameters passed */
+/* in registers (both floating point and integer) */
+
+ /* we store gpr 3 to gpr 10 (aligned to 4)
+ in the parents outgoing area */
+ std r3, 288+(0*8)(r1)
+ std r4, 288+(1*8)(r1)
+ std r5, 288+(2*8)(r1)
+ std r6, 288+(3*8)(r1)
+ std r7, 288+(4*8)(r1)
+ std r8, 288+(5*8)(r1)
+ std r9, 288+(6*8)(r1)
+ std r10, 288+(7*8)(r1)
+
+ /* next save fpr 1 to fpr 13 (aligned to 8) */
+ stfd f1, 128+(0*8)(r1)
+ stfd f2, 128+(1*8)(r1)
+ stfd f3, 128+(2*8)(r1)
+ stfd f4, 128+(3*8)(r1)
+ stfd f5, 128+(4*8)(r1)
+ stfd f6, 128+(5*8)(r1)
+ stfd f7, 128+(6*8)(r1)
+ stfd f8, 128+(7*8)(r1)
+ stfd f9, 128+(8*8)(r1)
+ stfd f10, 128+(9*8)(r1)
+ stfd f11, 128+(10*8)(r1)
+ stfd f12, 128+(11*8)(r1)
+ stfd f13, 128+(12*8)(r1)
+
+ /* set up registers for the routine that actually does the work */
+ /* get the context pointer from the trampoline */
+ mr r3,r11
+
+ /* now load up the pointer to the result storage */
+ addi r4,r1,112
+
+ /* now load up the pointer to the saved gpr registers */
+ addi r5,r1,288
+
+ /* now load up the pointer to the saved fpr registers */
+ addi r6,r1,128
+
+ /* make the call */
+ bl .ffi_closure_helper_DARWIN
+ nop
+
+ /* now r3 contains the return type */
+ /* so use it to look up in a table */
+ /* so we know how to deal with each type */
+
+ /* look up the proper starting point in table */
+ /* by using return type as offset */
+ addi r5,r1,112 /* get pointer to results area */
+ ld r4,LC..60(2) /* get address of jump table */
+ sldi r3,r3,2 /* now multiply return type by 4 */
+ lwzx r3,r4,r3 /* get the contents of that table value */
+ add r3,r3,r4 /* add contents of table to table address */
+ mtctr r3
+ bctr /* jump to it */
+
+L..60:
+ .long L..44-L..60 /* FFI_TYPE_VOID */
+ .long L..51-L..60 /* FFI_TYPE_INT */
+ .long L..47-L..60 /* FFI_TYPE_FLOAT */
+ .long L..46-L..60 /* FFI_TYPE_DOUBLE */
+ .long L..45-L..60 /* FFI_TYPE_LONGDOUBLE */
+ .long L..56-L..60 /* FFI_TYPE_UINT8 */
+ .long L..55-L..60 /* FFI_TYPE_SINT8 */
+ .long L..58-L..60 /* FFI_TYPE_UINT16 */
+ .long L..57-L..60 /* FFI_TYPE_SINT16 */
+ .long L..50-L..60 /* FFI_TYPE_UINT32 */
+ .long L..51-L..60 /* FFI_TYPE_SINT32 */
+ .long L..48-L..60 /* FFI_TYPE_UINT64 */
+ .long L..48-L..60 /* FFI_TYPE_SINT64 */
+ .long L..44-L..60 /* FFI_TYPE_STRUCT */
+ .long L..48-L..60 /* FFI_TYPE_POINTER */
+
+
+/* case long double */
+L..45:
+ lfd f1,0(r5)
+ lfd f2,8(r5)
+ b L..44
+
+/* case double */
+L..46:
+ lfd f1,0(r5)
+ b L..44
+
+/* case float */
+L..47:
+ lfs f1,0(r5)
+ b L..44
+
+/* case long long / pointer */
+L..48:
+ ld r3,0(r5)
+ b L..44
+
+/* case uint32 */
+L..50:
+ lwz r3,4(r5)
+ b L..44
+
+/* case int / sint32 */
+L..51:
+ lwa r3,4(r5)
+ b L..44
+
+/* case signed int8 */
+L..55:
+ lbz r3,7(r5)
+ extsb r3,r3
+ b L..44
+
+/* case unsigned int8 */
+L..56:
+ lbz r3,7(r5)
+ b L..44
+
+/* case signed int16 */
+L..57:
+ lha r3,6(r5)
+ b L..44
+
+/* case unsigned int16 */
+L..58:
+ lhz r3,6(r5)
+
+/* case void / done */
+L..44:
+ addi r1,r1,240 /* restore stack pointer */
+ ld r0,16(r1) /* get return address */
+ mtlr r0 /* reset link register */
+ blr
+
+#else /* ! __64BIT__ */
+
.long .ffi_closure_ASM, TOC[tc0], 0
.csect .text[PR]
.ffi_closure_ASM:
@@ -106,8 +261,8 @@ ffi_closure_ASM:
/* 24 Bytes (Linkage Area) */
/* 32 Bytes (params) */
/* 104 Bytes (13*8 from FPR) */
- /* 8 Bytes (result) */
- /* 168 Bytes */
+ /* 16 Bytes (result) */
+ /* 176 Bytes */
stwu r1,-176(r1) /* skip over caller save area
keep stack aligned to 16 */
@@ -177,7 +332,7 @@ L..60:
.long L..50-L..60 /* FFI_TYPE_INT */
.long L..47-L..60 /* FFI_TYPE_FLOAT */
.long L..46-L..60 /* FFI_TYPE_DOUBLE */
- .long L..46-L..60 /* FFI_TYPE_LONGDOUBLE */
+ .long L..45-L..60 /* FFI_TYPE_LONGDOUBLE */
.long L..56-L..60 /* FFI_TYPE_UINT8 */
.long L..55-L..60 /* FFI_TYPE_SINT8 */
.long L..58-L..60 /* FFI_TYPE_UINT16 */
@@ -190,6 +345,12 @@ L..60:
.long L..50-L..60 /* FFI_TYPE_POINTER */
+/* case long double */
+L..45:
+ lfd f1,0(r5)
+ lfd f2,8(r5)
+ b L..44
+
/* case double */
L..46:
lfd f1,0(r5)
@@ -211,31 +372,25 @@ L..50:
lwz r3,0(r5)
b L..44
-/* case signed int8 */
+/* case signed int8 */
L..55:
- addi r5,r5,3
- lbz r3,0(r5)
- slwi r3,r3,24
- srawi r3,r3,24
+ lbz r3,3(r5)
+ extsb r3,r3
b L..44
-/* case unsigned int8 */
+/* case unsigned int8 */
L..56:
- addi r5,r5,3
- lbz r3,0(r5)
+ lbz r3,3(r5)
b L..44
/* case signed int16 */
L..57:
- addi r5,r5,2
- lhz r3,0(r5)
- extsh r3,r3
+ lha r3,2(r5)
b L..44
/* case unsigned int16 */
L..58:
- addi r5,r5,2
- lhz r3,0(r5)
+ lhz r3,2(r5)
/* case void / done */
L..44:
@@ -243,5 +398,5 @@ L..44:
lwz r0,8(r1) /* get return address */
mtlr r0 /* reset link register */
blr
-
+#endif
/* END(ffi_closure_ASM) */
diff --git a/libffi/src/powerpc/ffi_darwin.c b/libffi/src/powerpc/ffi_darwin.c
index 501035d75d0..53dbdb2b244 100644
--- a/libffi/src/powerpc/ffi_darwin.c
+++ b/libffi/src/powerpc/ffi_darwin.c
@@ -3,7 +3,7 @@
Copyright (C) 1998 Geoffrey Keating
Copyright (C) 2001 John Hornkvist
- Copyright (C) 2002, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006, 2007, 2009 Free Software Foundation, Inc.
FFI support for Darwin and AIX.
@@ -80,27 +80,28 @@ enum { ASM_NEEDS_REGISTERS = 4 };
*/
-void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
+void ffi_prep_args(extended_cif *ecif, unsigned long *const stack)
{
const unsigned bytes = ecif->cif->bytes;
const unsigned flags = ecif->cif->flags;
/* 'stacktop' points at the previous backchain pointer. */
- unsigned *const stacktop = stack + (bytes / sizeof(unsigned));
+ unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long));
/* 'fpr_base' points at the space for fpr1, and grows upwards as
we use FPR registers. */
- double *fpr_base = (double*) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;
+ double *fpr_base = (double *) ((stacktop - ASM_NEEDS_REGISTERS)
+ - NUM_FPR_ARG_REGISTERS);
int fparg_count = 0;
/* 'next_arg' grows up as we put parameters in it. */
- unsigned *next_arg = stack + 6; /* 6 reserved positions. */
+ unsigned long *next_arg = (unsigned long *) stack + 6; /* 6 reserved positions. */
- int i = ecif->cif->nargs;
+ int i;
double double_tmp;
void **p_argv = ecif->avalue;
- unsigned gprvalue;
+ unsigned long gprvalue;
ffi_type** ptr = ecif->cif->arg_types;
char *dest_cpy;
unsigned size_al = 0;
@@ -115,12 +116,10 @@ void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
Return values are referenced by r3, so r4 is the first parameter. */
if (flags & FLAG_RETVAL_REFERENCE)
- *next_arg++ = (unsigned)(char *)ecif->rvalue;
+ *next_arg++ = (unsigned long)(char *)ecif->rvalue;
/* Now for the arguments. */
- for (;
- i > 0;
- i--, ptr++, p_argv++)
+ for (i = ecif->cif->nargs; i > 0; i--, ptr++, p_argv++)
{
switch ((*ptr)->type)
{
@@ -144,7 +143,11 @@ void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
*(double *)next_arg = double_tmp;
else
*fpr_base++ = double_tmp;
+#ifdef POWERPC64
+ next_arg++;
+#else
next_arg += 2;
+#endif
fparg_count++;
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
break;
@@ -152,42 +155,69 @@ void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
case FFI_TYPE_LONGDOUBLE:
- double_tmp = ((double *)*p_argv)[0];
- if (fparg_count >= NUM_FPR_ARG_REGISTERS)
- *(double *)next_arg = double_tmp;
+#ifdef POWERPC64
+ if (fparg_count < NUM_FPR_ARG_REGISTERS)
+ *(long double *) fpr_base++ = *(long double *) *p_argv;
else
- *fpr_base++ = double_tmp;
+ *(long double *) next_arg = *(long double *) *p_argv;
next_arg += 2;
- fparg_count++;
- double_tmp = ((double *)*p_argv)[1];
- if (fparg_count >= NUM_FPR_ARG_REGISTERS)
- *(double *)next_arg = double_tmp;
+ fparg_count += 2;
+#else
+ double_tmp = *((double *) *p_argv);
+ if (fparg_count < NUM_FPR_ARG_REGISTERS)
+ *fpr_base++ = double_tmp;
else
+ *(double *) next_arg = double_tmp;
+
+ double_tmp = ((double *) *p_argv)[1];
+ if (fparg_count < NUM_FPR_ARG_REGISTERS)
*fpr_base++ = double_tmp;
+ else
+ *(double *) next_arg = double_tmp;
next_arg += 2;
fparg_count++;
+#endif
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
break;
#endif
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
- *(long long *)next_arg = *(long long *)*p_argv;
+#ifdef POWERPC64
+ gprvalue = *(long long *) p_argv;
+ goto putgpr;
+#else
+ *(long long *) next_arg = *(long long *) *p_argv;
next_arg+=2;
+#endif
break;
+ case FFI_TYPE_POINTER:
+ gprvalue = *(unsigned long *) *p_argv;
+ goto putgpr;
case FFI_TYPE_UINT8:
- gprvalue = *(unsigned char *)*p_argv;
+ gprvalue = *(unsigned char *) *p_argv;
goto putgpr;
case FFI_TYPE_SINT8:
- gprvalue = *(signed char *)*p_argv;
+ gprvalue = *(signed char *) *p_argv;
goto putgpr;
case FFI_TYPE_UINT16:
- gprvalue = *(unsigned short *)*p_argv;
+ gprvalue = *(unsigned short *) *p_argv;
goto putgpr;
case FFI_TYPE_SINT16:
- gprvalue = *(signed short *)*p_argv;
+ gprvalue = *(signed short *) *p_argv;
goto putgpr;
case FFI_TYPE_STRUCT:
+#ifdef POWERPC64
+ dest_cpy = (char *) next_arg;
+ size_al = (*ptr)->size;
+ if ((*ptr)->elements[0]->type == 3)
+ size_al = ALIGN((*ptr)->size, 8);
+ if (size_al < 3 && ecif->cif->abi == FFI_DARWIN)
+ dest_cpy += 4 - size_al;
+
+ memcpy ((char *) dest_cpy, (char *) *p_argv, size_al);
+ next_arg += (size_al + 7) / 8;
+#else
dest_cpy = (char *) next_arg;
/* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
@@ -204,13 +234,16 @@ void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
memcpy((char *)dest_cpy, (char *)*p_argv, size_al);
next_arg += (size_al + 3) / 4;
+#endif
break;
case FFI_TYPE_INT:
- case FFI_TYPE_UINT32:
case FFI_TYPE_SINT32:
- case FFI_TYPE_POINTER:
- gprvalue = *(unsigned *)*p_argv;
+ gprvalue = *(signed int *) *p_argv;
+ goto putgpr;
+
+ case FFI_TYPE_UINT32:
+ gprvalue = *(unsigned int *) *p_argv;
putgpr:
*next_arg++ = gprvalue;
break;
@@ -324,6 +357,9 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
+#ifdef POWERPC64
+ case FFI_TYPE_POINTER:
+#endif
flags |= FLAG_RETURNS_64BITS;
break;
@@ -387,11 +423,14 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
case FFI_TYPE_STRUCT:
size_al = (*ptr)->size;
/* If the first member of the struct is a double, then align
- the struct to double-word.
- Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3. */
- if ((*ptr)->elements[0]->type == 3)
+ the struct to double-word. */
+ if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
size_al = ALIGN((*ptr)->size, 8);
+#ifdef POWERPC64
+ intarg_count += (size_al + 7) / 8;
+#else
intarg_count += (size_al + 3) / 4;
+#endif
break;
default:
@@ -410,8 +449,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
/* Stack space. */
+#ifdef POWERPC64
+ if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS)
+ bytes += (intarg_count + fparg_count) * sizeof(long);
+#else
if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
+#endif
else
bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
@@ -424,9 +468,9 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
return FFI_OK;
}
-extern void ffi_call_AIX(extended_cif *, unsigned, unsigned, unsigned *,
+extern void ffi_call_AIX(extended_cif *, long, unsigned, unsigned *,
void (*fn)(void), void (*fn2)(void));
-extern void ffi_call_DARWIN(extended_cif *, unsigned, unsigned, unsigned *,
+extern void ffi_call_DARWIN(extended_cif *, long, unsigned, unsigned *,
void (*fn)(void), void (*fn2)(void));
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
@@ -450,11 +494,11 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
switch (cif->abi)
{
case FFI_AIX:
- ffi_call_AIX(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn,
+ ffi_call_AIX(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
ffi_prep_args);
break;
case FFI_DARWIN:
- ffi_call_DARWIN(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn,
+ ffi_call_DARWIN(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
ffi_prep_args);
break;
default:
@@ -645,26 +689,19 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
void ** avalue;
ffi_type ** arg_types;
long i, avn;
- long nf; /* number of floating registers already used. */
- long ng; /* number of general registers already used. */
ffi_cif * cif;
- double temp;
+ ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS;
unsigned size_al;
- union ldu temp_ld;
cif = closure->cif;
avalue = alloca(cif->nargs * sizeof(void *));
- nf = 0;
- ng = 0;
-
/* Copy the caller's structure return value address so that the closure
returns the data directly to the caller. */
if (cif->rtype->type == FFI_TYPE_STRUCT)
{
rvalue = (void *) *pgr;
pgr++;
- ng++;
}
i = 0;
@@ -678,58 +715,82 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
{
case FFI_TYPE_SINT8:
case FFI_TYPE_UINT8:
+#ifdef POWERPC64
+ avalue[i] = (char *) pgr + 7;
+#else
avalue[i] = (char *) pgr + 3;
- ng++;
+#endif
pgr++;
break;
case FFI_TYPE_SINT16:
case FFI_TYPE_UINT16:
+#ifdef POWERPC64
+ avalue[i] = (char *) pgr + 6;
+#else
avalue[i] = (char *) pgr + 2;
- ng++;
+#endif
pgr++;
break;
case FFI_TYPE_SINT32:
case FFI_TYPE_UINT32:
+#ifdef POWERPC64
+ avalue[i] = (char *) pgr + 4;
+#else
case FFI_TYPE_POINTER:
avalue[i] = pgr;
- ng++;
+#endif
pgr++;
break;
case FFI_TYPE_STRUCT:
+#ifdef POWERPC64
+ size_al = arg_types[i]->size;
+ if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
+ size_al = ALIGN (arg_types[i]->size, 8);
+ if (size_al < 3 && cif->abi == FFI_DARWIN)
+ avalue[i] = (void *) pgr + 8 - size_al;
+ else
+ avalue[i] = (void *) pgr;
+ pgr += (size_al + 7) / 8;
+#else
/* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
SI 4 bytes) are aligned as if they were those modes. */
size_al = arg_types[i]->size;
/* If the first member of the struct is a double, then align
- the struct to double-word.
- Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3. */
- if (arg_types[i]->elements[0]->type == 3)
+ the struct to double-word. */
+ if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
size_al = ALIGN(arg_types[i]->size, 8);
if (size_al < 3 && cif->abi == FFI_DARWIN)
avalue[i] = (void*) pgr + 4 - size_al;
else
avalue[i] = (void*) pgr;
- ng += (size_al + 3) / 4;
pgr += (size_al + 3) / 4;
+#endif
break;
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
+#ifdef POWERPC64
+ case FFI_TYPE_POINTER:
+ avalue[i] = pgr;
+ pgr++;
+ break;
+#else
/* Long long ints are passed in two gpr's. */
avalue[i] = pgr;
- ng += 2;
pgr += 2;
break;
+#endif
case FFI_TYPE_FLOAT:
/* A float value consumes a GPR.
There are 13 64bit floating point registers. */
- if (nf < NUM_FPR_ARG_REGISTERS)
+ if (pfr < end_pfr)
{
- temp = pfr->d;
- pfr->f = (float)temp;
+ double temp = pfr->d;
+ pfr->f = (float) temp;
avalue[i] = pfr;
pfr++;
}
@@ -737,15 +798,13 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
{
avalue[i] = pgr;
}
- nf++;
- ng++;
pgr++;
break;
case FFI_TYPE_DOUBLE:
/* A double value consumes two GPRs.
There are 13 64bit floating point registers. */
- if (nf < NUM_FPR_ARG_REGISTERS)
+ if (pfr < end_pfr)
{
avalue[i] = pfr;
pfr++;
@@ -754,17 +813,36 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
{
avalue[i] = pgr;
}
- nf++;
- ng += 2;
+#ifdef POWERPC64
+ pgr++;
+#else
pgr += 2;
+#endif
break;
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
case FFI_TYPE_LONGDOUBLE:
+#ifdef POWERPC64
+ if (pfr + 1 < end_pfr)
+ {
+ avalue[i] = pfr;
+ pfr += 2;
+ }
+ else
+ {
+ if (pfr < end_pfr)
+ {
+ *pgr = *(unsigned long *) pfr;
+ pfr++;
+ }
+ avalue[i] = pgr;
+ }
+ pgr += 2;
+#else /* POWERPC64 */
/* A long double value consumes four GPRs and two FPRs.
There are 13 64bit floating point registers. */
- if (nf < NUM_FPR_ARG_REGISTERS - 1)
+ if (pfr + 1 < end_pfr)
{
avalue[i] = pfr;
pfr += 2;
@@ -772,8 +850,9 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
/* Here we have the situation where one part of the long double
is stored in fpr13 and the other part is already on the stack.
We use a union to pass the long double to avalue[i]. */
- else if (nf == NUM_FPR_ARG_REGISTERS - 1)
+ else if (pfr + 1 == end_pfr)
{
+ union ldu temp_ld;
memcpy (&temp_ld.lb[0], pfr, sizeof(ldbits));
memcpy (&temp_ld.lb[1], pgr + 2, sizeof(ldbits));
avalue[i] = &temp_ld.ld;
@@ -782,9 +861,8 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
{
avalue[i] = pgr;
}
- nf += 2;
- ng += 4;
pgr += 4;
+#endif /* POWERPC64 */
break;
#endif
default:
diff --git a/libffi/src/powerpc/ffitarget.h b/libffi/src/powerpc/ffitarget.h
index 269f573987c..b4f992e6df4 100644
--- a/libffi/src/powerpc/ffitarget.h
+++ b/libffi/src/powerpc/ffitarget.h
@@ -30,7 +30,11 @@
/* ---- System specific configurations ----------------------------------- */
-#if defined (POWERPC) && defined (__powerpc64__)
+#if defined (POWERPC) && defined (__powerpc64__) /* linux64 */
+#define POWERPC64
+#elif defined (POWERPC_DARWIN) && defined (__ppc64__) /* Darwin */
+#define POWERPC64
+#elif defined (POWERPC_AIX) && defined (__64BIT__) /* AIX64 */
#define POWERPC64
#endif
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index e4d2578017b..68bf89705d6 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,15 @@
+2009-11-30 Janus Weil <janus@gcc.gnu.org>
+
+ * gfortran.map: Add _gfortran_is_extension_of.
+ * Makefile.am: Add intrinsics/extends_type_of.c.
+ * Makefile.in: Regenerated.
+ * intrinsics/extends_type_of.c: New file.
+
+2009-11-30 Kai Tietz <Kai.Tietz@onevision.com>
+
+ * io/unix.c (find_file): Add variable id conditionally for
+ mingw targets.
+
2009-11-28 Jakub Jelinek <jakub@redhat.com>
* intrinsics/pack_generic.c (pack_internal): Remove unused
diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am
index db086bbc6c5..bd767a2e679 100644
--- a/libgfortran/Makefile.am
+++ b/libgfortran/Makefile.am
@@ -85,6 +85,7 @@ intrinsics/eoshift2.c \
intrinsics/erfc_scaled.c \
intrinsics/etime.c \
intrinsics/exit.c \
+intrinsics/extends_type_of.c \
intrinsics/fnum.c \
intrinsics/gerror.c \
intrinsics/getcwd.c \
diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in
index 8fca11eaa1c..9bc8f11426d 100644
--- a/libgfortran/Makefile.in
+++ b/libgfortran/Makefile.in
@@ -433,15 +433,15 @@ am__libgfortran_la_SOURCES_DIST = runtime/backtrace.c runtime/bounds.c \
intrinsics/date_and_time.c intrinsics/dtime.c intrinsics/env.c \
intrinsics/eoshift0.c intrinsics/eoshift2.c \
intrinsics/erfc_scaled.c intrinsics/etime.c intrinsics/exit.c \
- intrinsics/fnum.c intrinsics/gerror.c intrinsics/getcwd.c \
- intrinsics/getlog.c intrinsics/getXid.c intrinsics/hostnm.c \
- intrinsics/ierrno.c intrinsics/ishftc.c \
- intrinsics/iso_c_generated_procs.c intrinsics/iso_c_binding.c \
- intrinsics/kill.c intrinsics/link.c intrinsics/malloc.c \
- intrinsics/mvbits.c intrinsics/move_alloc.c \
- intrinsics/pack_generic.c intrinsics/perror.c \
- intrinsics/selected_char_kind.c intrinsics/signal.c \
- intrinsics/size.c intrinsics/sleep.c \
+ intrinsics/extends_type_of.c intrinsics/fnum.c \
+ intrinsics/gerror.c intrinsics/getcwd.c intrinsics/getlog.c \
+ intrinsics/getXid.c intrinsics/hostnm.c intrinsics/ierrno.c \
+ intrinsics/ishftc.c intrinsics/iso_c_generated_procs.c \
+ intrinsics/iso_c_binding.c intrinsics/kill.c intrinsics/link.c \
+ intrinsics/malloc.c intrinsics/mvbits.c \
+ intrinsics/move_alloc.c intrinsics/pack_generic.c \
+ intrinsics/perror.c intrinsics/selected_char_kind.c \
+ intrinsics/signal.c intrinsics/size.c intrinsics/sleep.c \
intrinsics/spread_generic.c intrinsics/string_intrinsics.c \
intrinsics/system.c intrinsics/rand.c intrinsics/random.c \
intrinsics/rename.c intrinsics/reshape_generic.c \
@@ -725,15 +725,16 @@ am__objects_36 = associated.lo abort.lo access.lo args.lo \
bit_intrinsics.lo c99_functions.lo chdir.lo chmod.lo clock.lo \
cpu_time.lo cshift0.lo ctime.lo date_and_time.lo dtime.lo \
env.lo eoshift0.lo eoshift2.lo erfc_scaled.lo etime.lo exit.lo \
- fnum.lo gerror.lo getcwd.lo getlog.lo getXid.lo hostnm.lo \
- ierrno.lo ishftc.lo iso_c_generated_procs.lo iso_c_binding.lo \
- kill.lo link.lo malloc.lo mvbits.lo move_alloc.lo \
- pack_generic.lo perror.lo selected_char_kind.lo signal.lo \
- size.lo sleep.lo spread_generic.lo string_intrinsics.lo \
- system.lo rand.lo random.lo rename.lo reshape_generic.lo \
- reshape_packed.lo selected_int_kind.lo selected_real_kind.lo \
- stat.lo symlnk.lo system_clock.lo time.lo transpose_generic.lo \
- umask.lo unlink.lo unpack_generic.lo in_pack_generic.lo \
+ extends_type_of.lo fnum.lo gerror.lo getcwd.lo getlog.lo \
+ getXid.lo hostnm.lo ierrno.lo ishftc.lo \
+ iso_c_generated_procs.lo iso_c_binding.lo kill.lo link.lo \
+ malloc.lo mvbits.lo move_alloc.lo pack_generic.lo perror.lo \
+ selected_char_kind.lo signal.lo size.lo sleep.lo \
+ spread_generic.lo string_intrinsics.lo system.lo rand.lo \
+ random.lo rename.lo reshape_generic.lo reshape_packed.lo \
+ selected_int_kind.lo selected_real_kind.lo stat.lo symlnk.lo \
+ system_clock.lo time.lo transpose_generic.lo umask.lo \
+ unlink.lo unpack_generic.lo in_pack_generic.lo \
in_unpack_generic.lo
am__objects_37 =
am__objects_38 = _abs_c4.lo _abs_c8.lo _abs_c10.lo _abs_c16.lo \
@@ -1030,6 +1031,7 @@ intrinsics/eoshift2.c \
intrinsics/erfc_scaled.c \
intrinsics/etime.c \
intrinsics/exit.c \
+intrinsics/extends_type_of.c \
intrinsics/fnum.c \
intrinsics/gerror.c \
intrinsics/getcwd.c \
@@ -1892,6 +1894,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exponent_r16.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exponent_r4.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exponent_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extends_type_of.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fbuf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_pos.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmain.Plo@am__quote@
@@ -5478,6 +5481,13 @@ exit.lo: intrinsics/exit.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exit.lo `test -f 'intrinsics/exit.c' || echo '$(srcdir)/'`intrinsics/exit.c
+extends_type_of.lo: intrinsics/extends_type_of.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT extends_type_of.lo -MD -MP -MF $(DEPDIR)/extends_type_of.Tpo -c -o extends_type_of.lo `test -f 'intrinsics/extends_type_of.c' || echo '$(srcdir)/'`intrinsics/extends_type_of.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/extends_type_of.Tpo $(DEPDIR)/extends_type_of.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/extends_type_of.c' object='extends_type_of.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o extends_type_of.lo `test -f 'intrinsics/extends_type_of.c' || echo '$(srcdir)/'`intrinsics/extends_type_of.c
+
fnum.lo: intrinsics/fnum.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fnum.lo -MD -MP -MF $(DEPDIR)/fnum.Tpo -c -o fnum.lo `test -f 'intrinsics/fnum.c' || echo '$(srcdir)/'`intrinsics/fnum.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/fnum.Tpo $(DEPDIR)/fnum.Plo
diff --git a/libgfortran/gfortran.map b/libgfortran/gfortran.map
index a149332d071..3541d142a7b 100644
--- a/libgfortran/gfortran.map
+++ b/libgfortran/gfortran.map
@@ -1095,6 +1095,7 @@ GFORTRAN_1.2 {
global:
_gfortran_clz128;
_gfortran_ctz128;
+ _gfortran_is_extension_of;
} GFORTRAN_1.1;
F2C_1.0 {
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index 011d426471b..8b324759a73 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -1287,6 +1287,9 @@ find_file (const char *file, gfc_charlen_type file_len)
char path[PATH_MAX + 1];
struct stat st[2];
gfc_unit *u;
+#if defined(__MINGW32__) && !HAVE_WORKING_STAT
+ uint64_t id = 0ULL;
+#endif
if (unpack_filename (path, file, file_len))
return NULL;
@@ -1295,7 +1298,7 @@ find_file (const char *file, gfc_charlen_type file_len)
return NULL;
#if defined(__MINGW32__) && !HAVE_WORKING_STAT
- id_from_path (path);
+ id = id_from_path (path);
#endif
__gthread_mutex_lock (&unit_lock);
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 070d82f2ac8..175926d3cad 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,8 @@
+2009-11-30 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * testsuite/lib/libgomp.exp (libgomp_init): Add host-dependent
+ settings for LC_ALL and LANG.
+
2009-11-25 Jakub Jelinek <jakub@redhat.com>
PR fortran/42162
diff --git a/libgomp/testsuite/lib/libgomp.exp b/libgomp/testsuite/lib/libgomp.exp
index 972d4a1fdd3..0c8e49f8d85 100644
--- a/libgomp/testsuite/lib/libgomp.exp
+++ b/libgomp/testsuite/lib/libgomp.exp
@@ -66,6 +66,13 @@ proc libgomp_init { args } {
setenv LC_ALL C
setenv LANG C
+ # Many hosts now default to a non-ASCII C locale, however, so
+ # they can set a charset encoding here if they need.
+ if { [ishost "*-*-cygwin*"] } {
+ setenv LC_ALL C.ASCII
+ setenv LANG C.ASCII
+ }
+
if ![info exists GCC_UNDER_TEST] then {
if [info exists TOOL_EXECUTABLE] {
set GCC_UNDER_TEST $TOOL_EXECUTABLE
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 57b5fe21f0f..11b94ba796f 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,13 @@
+2009-12-02 Ben Elliston <bje@au.ibm.com>
+
+ * java/net/natVMURLConnection.cc (guessContentTypeFromBuffer):
+ Mark `bytes' and `valid' parameters as potentially unused.
+
+2009-11-30 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * testsuite/lib/libjava.exp (libjava_init): Add host-dependent
+ settings for LC_ALL and LANG.
+
2009-11-30 Ben Elliston <bje@au.ibm.com>
* jni.cc (_Jv_JNI_GetObjectRefType): Mark `object' parameter as
diff --git a/libjava/java/net/natVMURLConnection.cc b/libjava/java/net/natVMURLConnection.cc
index a683fc6fdaf..0a30a219760 100644
--- a/libjava/java/net/natVMURLConnection.cc
+++ b/libjava/java/net/natVMURLConnection.cc
@@ -61,8 +61,8 @@ java::net::VMURLConnection::init ()
}
::java::lang::String *
-java::net::VMURLConnection::guessContentTypeFromBuffer (jbyteArray bytes,
- jint valid)
+java::net::VMURLConnection::guessContentTypeFromBuffer (jbyteArray bytes __attribute__ ((unused)),
+ jint valid __attribute__ ((unused)))
{
#if defined (HAVE_MAGIC_T) && defined (HAVE_MAGIC_H) && defined (USE_LTDL)
const char *result;
diff --git a/libjava/testsuite/lib/libjava.exp b/libjava/testsuite/lib/libjava.exp
index 510e4ac80d8..b05c56843cc 100644
--- a/libjava/testsuite/lib/libjava.exp
+++ b/libjava/testsuite/lib/libjava.exp
@@ -145,6 +145,13 @@ proc libjava_init { args } {
setenv LC_ALL C
setenv LANG C
+ # Many hosts now default to a non-ASCII C locale, however, so
+ # they can set a charset encoding here if they need.
+ if { [ishost "*-*-cygwin*"] } {
+ setenv LC_ALL C.ASCII
+ setenv LANG C.ASCII
+ }
+
if { $libjava_initialized == 1 } { return; }
if ![info exists GCJ_UNDER_TEST] {
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index a6ff6266e06..768e207c528 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,58 @@
+2009-11-30 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * testsuite/lib/libstdc++.exp (libstdc++_init): Add host-dependent
+ settings for LC_ALL and LANG.
+
+2009-11-30 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * libstdc++-v3/acinclude.m4 (GLIBCXX_ENABLE_SYMVERS): Don't disable
+ on PE targets.
+ * libstdc++-v3/configure: Regenerate.
+ * libstdc++-v3/configure.host: Add libtool DLL options for Cygwin
+ and MinGW platforms.
+
+ * libstdc++-v3/include/bits/c++config (_GLIBCXX_VISIBILITY_ATTR): On
+ platforms that don't support visibility, allow them to declare a macro
+ _GLIBCXX_PSEUDO_VISIBILITY that is applied in place of visibility.
+ (_GLIBCXX_PSEUDO_VISIBILITY): Supply empty default if not declared by
+ CPU- or OS-specific headers.
+
+ * libstdc++-v3/config/os/newlib/os_defines.h
+ (_GLIBCXX_PSEUDO_VISIBILITY_default): New macro for dllimport.
+ (_GLIBCXX_PSEUDO_VISIBILITY_hidden): New empty macro.
+ (_GLIBCXX_PSEUDO_VISIBILITY): Evaluate to one of the above.
+ * libstdc++-v3/config/os/mingw32/os_defines.h
+ (_GLIBCXX_PSEUDO_VISIBILITY_default,
+ _GLIBCXX_PSEUDO_VISIBILITY_hidden,
+ _GLIBCXX_PSEUDO_VISIBILITY): Likewise.
+
+2009-11-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/tr1_impl/functional: Remove file, copy its contents,
+ trivially adjusted...
+ * include/std/functional: ... here, and...
+ * include/tr1/functional: ... here.
+ * include/Makefile.am: Adjust.
+ * include/Makefile.in: Regenerate.
+
+2009-11-30 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/tr1_impl/functional (function): Add rvalue support and
+ tweak doxygen markup.
+ * testsuite/20_util/function/assign/move.cc: New.
+ * testsuite/20_util/function/cons/move.cc: New.
+ * testsuite/20_util/function/invoke/move_only.cc: New.
+ * testsuite/20_util/function/cmp/cmp_neg.cc: New.
+ * testsuite/20_util/function/1.cc: Copy from testsuite/tr1/.
+ * testsuite/20_util/function/2.cc: Likewise.
+ * testsuite/20_util/function/3.cc: Likewise.
+ * testsuite/20_util/function/4.cc: Likewise.
+ * testsuite/20_util/function/5.cc: Likewise.
+ * testsuite/20_util/function/6.cc: Likewise.
+ * testsuite/20_util/function/7.cc: Likewise.
+ * testsuite/20_util/function/8.cc: Likewise.
+ * testsuite/20_util/function/9.cc: Likewise.
+
2009-11-29 Jonathan Wakely <jwakely.gcc@gmail.com>
* doc/doxygen/user.cfg.in: Add __GXX_RTTI to PREDEFINED macros.
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index aba9a1b2f52..e0c698d75c2 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2737,7 +2737,7 @@ if test x$enable_symvers = xyes ; then
else
if test $with_gnu_ld = yes ; then
case ${target_os} in
- cygwin* | pe | mingw32* | hpux*)
+ hpux*)
enable_symvers=no ;;
*)
enable_symvers=gnu ;;
diff --git a/libstdc++-v3/config/os/mingw32/os_defines.h b/libstdc++-v3/config/os/mingw32/os_defines.h
index 7b4e8066457..5435ce9ae84 100644
--- a/libstdc++-v3/config/os/mingw32/os_defines.h
+++ b/libstdc++-v3/config/os/mingw32/os_defines.h
@@ -45,6 +45,15 @@
#undef NOMINMAX
#define NOMINMAX 1
+#if defined (_GLIBCXX_DLL)
+#define _GLIBCXX_PSEUDO_VISIBILITY_default __attribute__ ((__dllimport__))
+#else
+#define _GLIBCXX_PSEUDO_VISIBILITY_default
+#endif
+#define _GLIBCXX_PSEUDO_VISIBILITY_hidden
+
+#define _GLIBCXX_PSEUDO_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY_ ## V
+
// See libstdc++/20806.
#define _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM 1
diff --git a/libstdc++-v3/config/os/newlib/os_defines.h b/libstdc++-v3/config/os/newlib/os_defines.h
index fbc886365ff..1ff3d4846cb 100644
--- a/libstdc++-v3/config/os/newlib/os_defines.h
+++ b/libstdc++-v3/config/os/newlib/os_defines.h
@@ -36,6 +36,15 @@
#ifdef __CYGWIN__
#define _GLIBCXX_GTHREAD_USE_WEAK 0
+#if defined (_GLIBCXX_DLL)
+#define _GLIBCXX_PSEUDO_VISIBILITY_default __attribute__ ((__dllimport__))
+#else
+#define _GLIBCXX_PSEUDO_VISIBILITY_default
+#endif
+#define _GLIBCXX_PSEUDO_VISIBILITY_hidden
+
+#define _GLIBCXX_PSEUDO_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY_ ## V
+
// See libstdc++/20806.
#define _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM 1
#endif
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 75adc589e12..4f5d51783d6 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -58050,7 +58050,7 @@ if test x$enable_symvers = xyes ; then
else
if test $with_gnu_ld = yes ; then
case ${target_os} in
- cygwin* | pe | mingw32* | hpux*)
+ hpux*)
enable_symvers=no ;;
*)
enable_symvers=gnu ;;
diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
index de7745a1286..02292b016d0 100644
--- a/libstdc++-v3/configure.host
+++ b/libstdc++-v3/configure.host
@@ -209,6 +209,7 @@ case "${host_os}" in
;;
cygwin*)
os_include_dir="os/newlib"
+ OPT_LDFLAGS="${OPT_LDFLAGS} -no-undefined -bindir \$(bindir)"
;;
darwin | darwin[1-7] | darwin[1-7].*)
# On Darwin, performance is improved if libstdc++ is single-module.
@@ -258,6 +259,7 @@ case "${host_os}" in
mingw32*)
os_include_dir="os/mingw32"
error_constants_dir="os/mingw32"
+ OPT_LDFLAGS="${OPT_LDFLAGS} -no-undefined -bindir \$(bindir)"
;;
netbsd*)
os_include_dir="os/bsd/netbsd"
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 47253e681c9..8d4ece7ee44 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -609,7 +609,6 @@ tr1_impl_headers = \
${tr1_impl_srcdir}/cstdlib \
${tr1_impl_srcdir}/cwchar \
${tr1_impl_srcdir}/cwctype \
- ${tr1_impl_srcdir}/functional \
${tr1_impl_srcdir}/hashtable \
${tr1_impl_srcdir}/hashtable_policy.h \
${tr1_impl_srcdir}/regex \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 71e7489be36..221ae557530 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -849,7 +849,6 @@ tr1_impl_headers = \
${tr1_impl_srcdir}/cstdlib \
${tr1_impl_srcdir}/cwchar \
${tr1_impl_srcdir}/cwctype \
- ${tr1_impl_srcdir}/functional \
${tr1_impl_srcdir}/hashtable \
${tr1_impl_srcdir}/hashtable_policy.h \
${tr1_impl_srcdir}/regex \
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index f4f1f8b901f..3746696458a 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -42,7 +42,9 @@
#if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY
# define _GLIBCXX_VISIBILITY_ATTR(V) __attribute__ ((__visibility__ (#V)))
#else
-# define _GLIBCXX_VISIBILITY_ATTR(V)
+// If this is not supplied by the OS-specific or CPU-specific
+// headers included below, it will be defined to an empty default.
+# define _GLIBCXX_VISIBILITY_ATTR(V) _GLIBCXX_PSEUDO_VISIBILITY(V)
#endif
// Macros for deprecated.
@@ -275,6 +277,12 @@ namespace std
// Pick up any CPU-specific definitions.
#include <bits/cpu_defines.h>
+// If platform uses neither visibility nor psuedo-visibility,
+// specify empty default for namespace annotation macros.
+#ifndef _GLIBCXX_PSEUDO_VISIBILITY
+#define _GLIBCXX_PSEUDO_VISIBILITY(V)
+#endif
+
// Allow use of "export template." This is currently not a feature
// that g++ supports.
// #define _GLIBCXX_EXPORT_TEMPLATE 1
diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index e46a27df12a..eb10b348ad1 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -50,28 +50,2145 @@
#include <bits/stl_function.h>
#ifdef __GXX_EXPERIMENTAL_CXX0X__
-# if defined(_GLIBCXX_INCLUDE_AS_TR1)
-# error C++0x header cannot be included from TR1 header
-# endif
-# include <typeinfo>
-# include <new>
-# include <tuple>
-# include <type_traits>
-# include <bits/functional_hash.h>
-# include <ext/type_traits.h>
-# if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
-# include <tr1_impl/functional>
-# else
-# define _GLIBCXX_INCLUDE_AS_CXX0X
-# define _GLIBCXX_BEGIN_NAMESPACE_TR1
-# define _GLIBCXX_END_NAMESPACE_TR1
-# define _GLIBCXX_TR1
-# include <tr1_impl/functional>
-# undef _GLIBCXX_TR1
-# undef _GLIBCXX_END_NAMESPACE_TR1
-# undef _GLIBCXX_BEGIN_NAMESPACE_TR1
-# undef _GLIBCXX_INCLUDE_AS_CXX0X
-# endif
+
+#include <typeinfo>
+#include <new>
+#include <tuple>
+#include <type_traits>
+#include <bits/functional_hash.h>
+#include <ext/type_traits.h>
+
+namespace std
+{
+ template<typename _MemberPointer>
+ class _Mem_fn;
+
+ /**
+ * Actual implementation of _Has_result_type, which uses SFINAE to
+ * determine if the type _Tp has a publicly-accessible member type
+ * result_type.
+ */
+ template<typename _Tp>
+ class _Has_result_type_helper : __sfinae_types
+ {
+ template<typename _Up>
+ struct _Wrap_type
+ { };
+
+ template<typename _Up>
+ static __one __test(_Wrap_type<typename _Up::result_type>*);
+
+ template<typename _Up>
+ static __two __test(...);
+
+ public:
+ static const bool value = sizeof(__test<_Tp>(0)) == 1;
+ };
+
+ template<typename _Tp>
+ struct _Has_result_type
+ : integral_constant<bool,
+ _Has_result_type_helper<typename remove_cv<_Tp>::type>::value>
+ { };
+
+ /**
+ *
+ */
+ /// If we have found a result_type, extract it.
+ template<bool _Has_result_type, typename _Functor>
+ struct _Maybe_get_result_type
+ { };
+
+ template<typename _Functor>
+ struct _Maybe_get_result_type<true, _Functor>
+ {
+ typedef typename _Functor::result_type result_type;
+ };
+
+ /**
+ * Base class for any function object that has a weak result type, as
+ * defined in 3.3/3 of TR1.
+ */
+ template<typename _Functor>
+ struct _Weak_result_type_impl
+ : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor>
+ {
+ };
+
+ /// Retrieve the result type for a function type.
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(_ArgTypes...)>
+ {
+ typedef _Res result_type;
+ };
+
+ /// Retrieve the result type for a function reference.
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(&)(_ArgTypes...)>
+ {
+ typedef _Res result_type;
+ };
+
+ /// Retrieve the result type for a function pointer.
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(*)(_ArgTypes...)>
+ {
+ typedef _Res result_type;
+ };
+
+ /// Retrieve result type for a member function pointer.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)>
+ {
+ typedef _Res result_type;
+ };
+
+ /// Retrieve result type for a const member function pointer.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) const>
+ {
+ typedef _Res result_type;
+ };
+
+ /// Retrieve result type for a volatile member function pointer.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) volatile>
+ {
+ typedef _Res result_type;
+ };
+
+ /// Retrieve result type for a const volatile member function pointer.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)const volatile>
+ {
+ typedef _Res result_type;
+ };
+
+ /**
+ * Strip top-level cv-qualifiers from the function object and let
+ * _Weak_result_type_impl perform the real work.
+ */
+ template<typename _Functor>
+ struct _Weak_result_type
+ : _Weak_result_type_impl<typename remove_cv<_Functor>::type>
+ {
+ };
+
+ template<typename _Signature>
+ class result_of;
+
+ /**
+ * Actual implementation of result_of. When _Has_result_type is
+ * true, gets its result from _Weak_result_type. Otherwise, uses
+ * the function object's member template result to extract the
+ * result type.
+ */
+ template<bool _Has_result_type, typename _Signature>
+ struct _Result_of_impl;
+
+ // Handle member data pointers using _Mem_fn's logic
+ template<typename _Res, typename _Class, typename _T1>
+ struct _Result_of_impl<false, _Res _Class::*(_T1)>
+ {
+ typedef typename _Mem_fn<_Res _Class::*>
+ ::template _Result_type<_T1>::type type;
+ };
+
+ /**
+ * Determine whether we can determine a result type from @c Functor
+ * alone.
+ */
+ template<typename _Functor, typename... _ArgTypes>
+ class result_of<_Functor(_ArgTypes...)>
+ : public _Result_of_impl<
+ _Has_result_type<_Weak_result_type<_Functor> >::value,
+ _Functor(_ArgTypes...)>
+ {
+ };
+
+ /// We already know the result type for @c Functor; use it.
+ template<typename _Functor, typename... _ArgTypes>
+ struct _Result_of_impl<true, _Functor(_ArgTypes...)>
+ {
+ typedef typename _Weak_result_type<_Functor>::result_type type;
+ };
+
+ /**
+ * We need to compute the result type for this invocation the hard
+ * way.
+ */
+ template<typename _Functor, typename... _ArgTypes>
+ struct _Result_of_impl<false, _Functor(_ArgTypes...)>
+ {
+ typedef typename _Functor
+ ::template result<_Functor(_ArgTypes...)>::type type;
+ };
+
+ /**
+ * It is unsafe to access ::result when there are zero arguments, so we
+ * return @c void instead.
+ */
+ template<typename _Functor>
+ struct _Result_of_impl<false, _Functor()>
+ {
+ typedef void type;
+ };
+
+ /// Determines if the type _Tp derives from unary_function.
+ template<typename _Tp>
+ struct _Derives_from_unary_function : __sfinae_types
+ {
+ private:
+ template<typename _T1, typename _Res>
+ static __one __test(const volatile unary_function<_T1, _Res>*);
+
+ // It's tempting to change "..." to const volatile void*, but
+ // that fails when _Tp is a function type.
+ static __two __test(...);
+
+ public:
+ static const bool value = sizeof(__test((_Tp*)0)) == 1;
+ };
+
+ /// Determines if the type _Tp derives from binary_function.
+ template<typename _Tp>
+ struct _Derives_from_binary_function : __sfinae_types
+ {
+ private:
+ template<typename _T1, typename _T2, typename _Res>
+ static __one __test(const volatile binary_function<_T1, _T2, _Res>*);
+
+ // It's tempting to change "..." to const volatile void*, but
+ // that fails when _Tp is a function type.
+ static __two __test(...);
+
+ public:
+ static const bool value = sizeof(__test((_Tp*)0)) == 1;
+ };
+
+ /// Turns a function type into a function pointer type
+ template<typename _Tp, bool _IsFunctionType = is_function<_Tp>::value>
+ struct _Function_to_function_pointer
+ {
+ typedef _Tp type;
+ };
+
+ template<typename _Tp>
+ struct _Function_to_function_pointer<_Tp, true>
+ {
+ typedef _Tp* type;
+ };
+
+ /**
+ * Invoke a function object, which may be either a member pointer or a
+ * function object. The first parameter will tell which.
+ */
+ template<typename _Functor, typename... _Args>
+ inline
+ typename __gnu_cxx::__enable_if<
+ (!is_member_pointer<_Functor>::value
+ && !is_function<_Functor>::value
+ && !is_function<typename remove_pointer<_Functor>::type>::value),
+ typename result_of<_Functor(_Args...)>::type
+ >::__type
+ __invoke(_Functor& __f, _Args&... __args)
+ {
+ return __f(__args...);
+ }
+
+ template<typename _Functor, typename... _Args>
+ inline
+ typename __gnu_cxx::__enable_if<
+ (is_member_pointer<_Functor>::value
+ && !is_function<_Functor>::value
+ && !is_function<typename remove_pointer<_Functor>::type>::value),
+ typename result_of<_Functor(_Args...)>::type
+ >::__type
+ __invoke(_Functor& __f, _Args&... __args)
+ {
+ return mem_fn(__f)(__args...);
+ }
+
+ // To pick up function references (that will become function pointers)
+ template<typename _Functor, typename... _Args>
+ inline
+ typename __gnu_cxx::__enable_if<
+ (is_pointer<_Functor>::value
+ && is_function<typename remove_pointer<_Functor>::type>::value),
+ typename result_of<_Functor(_Args...)>::type
+ >::__type
+ __invoke(_Functor __f, _Args&... __args)
+ {
+ return __f(__args...);
+ }
+
+ /**
+ * Knowing which of unary_function and binary_function _Tp derives
+ * from, derives from the same and ensures that reference_wrapper
+ * will have a weak result type. See cases below.
+ */
+ template<bool _Unary, bool _Binary, typename _Tp>
+ struct _Reference_wrapper_base_impl;
+
+ // Not a unary_function or binary_function, so try a weak result type.
+ template<typename _Tp>
+ struct _Reference_wrapper_base_impl<false, false, _Tp>
+ : _Weak_result_type<_Tp>
+ { };
+
+ // unary_function but not binary_function
+ template<typename _Tp>
+ struct _Reference_wrapper_base_impl<true, false, _Tp>
+ : unary_function<typename _Tp::argument_type,
+ typename _Tp::result_type>
+ { };
+
+ // binary_function but not unary_function
+ template<typename _Tp>
+ struct _Reference_wrapper_base_impl<false, true, _Tp>
+ : binary_function<typename _Tp::first_argument_type,
+ typename _Tp::second_argument_type,
+ typename _Tp::result_type>
+ { };
+
+ // Both unary_function and binary_function. Import result_type to
+ // avoid conflicts.
+ template<typename _Tp>
+ struct _Reference_wrapper_base_impl<true, true, _Tp>
+ : unary_function<typename _Tp::argument_type,
+ typename _Tp::result_type>,
+ binary_function<typename _Tp::first_argument_type,
+ typename _Tp::second_argument_type,
+ typename _Tp::result_type>
+ {
+ typedef typename _Tp::result_type result_type;
+ };
+
+ /**
+ * Derives from unary_function or binary_function when it
+ * can. Specializations handle all of the easy cases. The primary
+ * template determines what to do with a class type, which may
+ * derive from both unary_function and binary_function.
+ */
+ template<typename _Tp>
+ struct _Reference_wrapper_base
+ : _Reference_wrapper_base_impl<
+ _Derives_from_unary_function<_Tp>::value,
+ _Derives_from_binary_function<_Tp>::value,
+ _Tp>
+ { };
+
+ // - a function type (unary)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res(_T1)>
+ : unary_function<_T1, _Res>
+ { };
+
+ // - a function type (binary)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res(_T1, _T2)>
+ : binary_function<_T1, _T2, _Res>
+ { };
+
+ // - a function pointer type (unary)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res(*)(_T1)>
+ : unary_function<_T1, _Res>
+ { };
+
+ // - a function pointer type (binary)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res(*)(_T1, _T2)>
+ : binary_function<_T1, _T2, _Res>
+ { };
+
+ // - a pointer to member function type (unary, no qualifiers)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res (_T1::*)()>
+ : unary_function<_T1*, _Res>
+ { };
+
+ // - a pointer to member function type (binary, no qualifiers)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2)>
+ : binary_function<_T1*, _T2, _Res>
+ { };
+
+ // - a pointer to member function type (unary, const)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res (_T1::*)() const>
+ : unary_function<const _T1*, _Res>
+ { };
+
+ // - a pointer to member function type (binary, const)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const>
+ : binary_function<const _T1*, _T2, _Res>
+ { };
+
+ // - a pointer to member function type (unary, volatile)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res (_T1::*)() volatile>
+ : unary_function<volatile _T1*, _Res>
+ { };
+
+ // - a pointer to member function type (binary, volatile)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) volatile>
+ : binary_function<volatile _T1*, _T2, _Res>
+ { };
+
+ // - a pointer to member function type (unary, const volatile)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res (_T1::*)() const volatile>
+ : unary_function<const volatile _T1*, _Res>
+ { };
+
+ // - a pointer to member function type (binary, const volatile)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const volatile>
+ : binary_function<const volatile _T1*, _T2, _Res>
+ { };
+
+ /// reference_wrapper
+ template<typename _Tp>
+ class reference_wrapper
+ : public _Reference_wrapper_base<typename remove_cv<_Tp>::type>
+ {
+ // If _Tp is a function type, we can't form result_of<_Tp(...)>,
+ // so turn it into a function pointer type.
+ typedef typename _Function_to_function_pointer<_Tp>::type
+ _M_func_type;
+
+ _Tp* _M_data;
+ public:
+ typedef _Tp type;
+
+ explicit
+ reference_wrapper(_Tp& __indata): _M_data(&__indata)
+ { }
+
+ reference_wrapper(const reference_wrapper<_Tp>& __inref):
+ _M_data(__inref._M_data)
+ { }
+
+ reference_wrapper&
+ operator=(const reference_wrapper<_Tp>& __inref)
+ {
+ _M_data = __inref._M_data;
+ return *this;
+ }
+
+ operator _Tp&() const
+ { return this->get(); }
+
+ _Tp&
+ get() const
+ { return *_M_data; }
+
+ template<typename... _Args>
+ typename result_of<_M_func_type(_Args...)>::type
+ operator()(_Args&... __args) const
+ {
+ return __invoke(get(), __args...);
+ }
+ };
+
+
+ // Denotes a reference should be taken to a variable.
+ template<typename _Tp>
+ inline reference_wrapper<_Tp>
+ ref(_Tp& __t)
+ { return reference_wrapper<_Tp>(__t); }
+
+ // Denotes a const reference should be taken to a variable.
+ template<typename _Tp>
+ inline reference_wrapper<const _Tp>
+ cref(const _Tp& __t)
+ { return reference_wrapper<const _Tp>(__t); }
+
+ template<typename _Tp>
+ inline reference_wrapper<_Tp>
+ ref(reference_wrapper<_Tp> __t)
+ { return ref(__t.get()); }
+
+ template<typename _Tp>
+ inline reference_wrapper<const _Tp>
+ cref(reference_wrapper<_Tp> __t)
+ { return cref(__t.get()); }
+
+ template<typename _Tp, bool>
+ struct _Mem_fn_const_or_non
+ {
+ typedef const _Tp& type;
+ };
+
+ template<typename _Tp>
+ struct _Mem_fn_const_or_non<_Tp, false>
+ {
+ typedef _Tp& type;
+ };
+
+ /**
+ * Derives from @c unary_function or @c binary_function, or perhaps
+ * nothing, depending on the number of arguments provided. The
+ * primary template is the basis case, which derives nothing.
+ */
+ template<typename _Res, typename... _ArgTypes>
+ struct _Maybe_unary_or_binary_function { };
+
+ /// Derives from @c unary_function, as appropriate.
+ template<typename _Res, typename _T1>
+ struct _Maybe_unary_or_binary_function<_Res, _T1>
+ : std::unary_function<_T1, _Res> { };
+
+ /// Derives from @c binary_function, as appropriate.
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Maybe_unary_or_binary_function<_Res, _T1, _T2>
+ : std::binary_function<_T1, _T2, _Res> { };
+
+ /// Implementation of @c mem_fn for member function pointers.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ class _Mem_fn<_Res (_Class::*)(_ArgTypes...)>
+ : public _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...>
+ {
+ typedef _Res (_Class::*_Functor)(_ArgTypes...);
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __object, const volatile _Class *,
+ _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
+ { return ((*__ptr).*__pmf)(__args...); }
+
+ public:
+ typedef _Res result_type;
+
+ explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+
+ // Handle objects
+ _Res
+ operator()(_Class& __object, _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ // Handle pointers
+ _Res
+ operator()(_Class* __object, _ArgTypes... __args) const
+ { return (__object->*__pmf)(__args...); }
+
+ // Handle smart pointers, references and pointers to derived
+ template<typename _Tp>
+ _Res
+ operator()(_Tp& __object, _ArgTypes... __args) const
+ { return _M_call(__object, &__object, __args...); }
+
+ private:
+ _Functor __pmf;
+ };
+
+ /// Implementation of @c mem_fn for const member function pointers.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const>
+ : public _Maybe_unary_or_binary_function<_Res, const _Class*,
+ _ArgTypes...>
+ {
+ typedef _Res (_Class::*_Functor)(_ArgTypes...) const;
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __object, const volatile _Class *,
+ _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
+ { return ((*__ptr).*__pmf)(__args...); }
+
+ public:
+ typedef _Res result_type;
+
+ explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+
+ // Handle objects
+ _Res
+ operator()(const _Class& __object, _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ // Handle pointers
+ _Res
+ operator()(const _Class* __object, _ArgTypes... __args) const
+ { return (__object->*__pmf)(__args...); }
+
+ // Handle smart pointers, references and pointers to derived
+ template<typename _Tp>
+ _Res operator()(_Tp& __object, _ArgTypes... __args) const
+ { return _M_call(__object, &__object, __args...); }
+
+ private:
+ _Functor __pmf;
+ };
+
+ /// Implementation of @c mem_fn for volatile member function pointers.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ class _Mem_fn<_Res (_Class::*)(_ArgTypes...) volatile>
+ : public _Maybe_unary_or_binary_function<_Res, volatile _Class*,
+ _ArgTypes...>
+ {
+ typedef _Res (_Class::*_Functor)(_ArgTypes...) volatile;
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __object, const volatile _Class *,
+ _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
+ { return ((*__ptr).*__pmf)(__args...); }
+
+ public:
+ typedef _Res result_type;
+
+ explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+
+ // Handle objects
+ _Res
+ operator()(volatile _Class& __object, _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ // Handle pointers
+ _Res
+ operator()(volatile _Class* __object, _ArgTypes... __args) const
+ { return (__object->*__pmf)(__args...); }
+
+ // Handle smart pointers, references and pointers to derived
+ template<typename _Tp>
+ _Res
+ operator()(_Tp& __object, _ArgTypes... __args) const
+ { return _M_call(__object, &__object, __args...); }
+
+ private:
+ _Functor __pmf;
+ };
+
+ /// Implementation of @c mem_fn for const volatile member function pointers.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const volatile>
+ : public _Maybe_unary_or_binary_function<_Res, const volatile _Class*,
+ _ArgTypes...>
+ {
+ typedef _Res (_Class::*_Functor)(_ArgTypes...) const volatile;
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __object, const volatile _Class *,
+ _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
+ { return ((*__ptr).*__pmf)(__args...); }
+
+ public:
+ typedef _Res result_type;
+
+ explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+
+ // Handle objects
+ _Res
+ operator()(const volatile _Class& __object, _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ // Handle pointers
+ _Res
+ operator()(const volatile _Class* __object, _ArgTypes... __args) const
+ { return (__object->*__pmf)(__args...); }
+
+ // Handle smart pointers, references and pointers to derived
+ template<typename _Tp>
+ _Res operator()(_Tp& __object, _ArgTypes... __args) const
+ { return _M_call(__object, &__object, __args...); }
+
+ private:
+ _Functor __pmf;
+ };
+
+
+ template<typename _Res, typename _Class>
+ class _Mem_fn<_Res _Class::*>
+ {
+ // This bit of genius is due to Peter Dimov, improved slightly by
+ // Douglas Gregor.
+ template<typename _Tp>
+ _Res&
+ _M_call(_Tp& __object, _Class *) const
+ { return __object.*__pm; }
+
+ template<typename _Tp, typename _Up>
+ _Res&
+ _M_call(_Tp& __object, _Up * const *) const
+ { return (*__object).*__pm; }
+
+ template<typename _Tp, typename _Up>
+ const _Res&
+ _M_call(_Tp& __object, const _Up * const *) const
+ { return (*__object).*__pm; }
+
+ template<typename _Tp>
+ const _Res&
+ _M_call(_Tp& __object, const _Class *) const
+ { return __object.*__pm; }
+
+ template<typename _Tp>
+ const _Res&
+ _M_call(_Tp& __ptr, const volatile void*) const
+ { return (*__ptr).*__pm; }
+
+ template<typename _Tp> static _Tp& __get_ref();
+
+ template<typename _Tp>
+ static __sfinae_types::__one __check_const(_Tp&, _Class*);
+ template<typename _Tp, typename _Up>
+ static __sfinae_types::__one __check_const(_Tp&, _Up * const *);
+ template<typename _Tp, typename _Up>
+ static __sfinae_types::__two __check_const(_Tp&, const _Up * const *);
+ template<typename _Tp>
+ static __sfinae_types::__two __check_const(_Tp&, const _Class*);
+ template<typename _Tp>
+ static __sfinae_types::__two __check_const(_Tp&, const volatile void*);
+
+ public:
+ template<typename _Tp>
+ struct _Result_type
+ : _Mem_fn_const_or_non<_Res,
+ (sizeof(__sfinae_types::__two)
+ == sizeof(__check_const<_Tp>(__get_ref<_Tp>(), (_Tp*)0)))>
+ { };
+
+ template<typename _Signature>
+ struct result;
+
+ template<typename _CVMem, typename _Tp>
+ struct result<_CVMem(_Tp)>
+ : public _Result_type<_Tp> { };
+
+ template<typename _CVMem, typename _Tp>
+ struct result<_CVMem(_Tp&)>
+ : public _Result_type<_Tp> { };
+
+ explicit
+ _Mem_fn(_Res _Class::*__pm) : __pm(__pm) { }
+
+ // Handle objects
+ _Res&
+ operator()(_Class& __object) const
+ { return __object.*__pm; }
+
+ const _Res&
+ operator()(const _Class& __object) const
+ { return __object.*__pm; }
+
+ // Handle pointers
+ _Res&
+ operator()(_Class* __object) const
+ { return __object->*__pm; }
+
+ const _Res&
+ operator()(const _Class* __object) const
+ { return __object->*__pm; }
+
+ // Handle smart pointers and derived
+ template<typename _Tp>
+ typename _Result_type<_Tp>::type
+ operator()(_Tp& __unknown) const
+ { return _M_call(__unknown, &__unknown); }
+
+ private:
+ _Res _Class::*__pm;
+ };
+
+ /**
+ * @brief Returns a function object that forwards to the member
+ * pointer @a pm.
+ */
+ template<typename _Tp, typename _Class>
+ inline _Mem_fn<_Tp _Class::*>
+ mem_fn(_Tp _Class::* __pm)
+ {
+ return _Mem_fn<_Tp _Class::*>(__pm);
+ }
+
+ /**
+ * @brief Determines if the given type _Tp is a function object
+ * should be treated as a subexpression when evaluating calls to
+ * function objects returned by bind(). [TR1 3.6.1]
+ */
+ template<typename _Tp>
+ struct is_bind_expression
+ { static const bool value = false; };
+
+ template<typename _Tp>
+ const bool is_bind_expression<_Tp>::value;
+
+ /**
+ * @brief Determines if the given type _Tp is a placeholder in a
+ * bind() expression and, if so, which placeholder it is. [TR1 3.6.2]
+ */
+ template<typename _Tp>
+ struct is_placeholder
+ { static const int value = 0; };
+
+ template<typename _Tp>
+ const int is_placeholder<_Tp>::value;
+
+ /// The type of placeholder objects defined by libstdc++.
+ template<int _Num> struct _Placeholder { };
+
+ /** @namespace std::placeholders
+ * @brief ISO C++ 0x entities sub namespace for functional.
+ *
+ * Define a large number of placeholders. There is no way to
+ * simplify this with variadic templates, because we're introducing
+ * unique names for each.
+ */
+ namespace placeholders
+ {
+ namespace
+ {
+ _Placeholder<1> _1;
+ _Placeholder<2> _2;
+ _Placeholder<3> _3;
+ _Placeholder<4> _4;
+ _Placeholder<5> _5;
+ _Placeholder<6> _6;
+ _Placeholder<7> _7;
+ _Placeholder<8> _8;
+ _Placeholder<9> _9;
+ _Placeholder<10> _10;
+ _Placeholder<11> _11;
+ _Placeholder<12> _12;
+ _Placeholder<13> _13;
+ _Placeholder<14> _14;
+ _Placeholder<15> _15;
+ _Placeholder<16> _16;
+ _Placeholder<17> _17;
+ _Placeholder<18> _18;
+ _Placeholder<19> _19;
+ _Placeholder<20> _20;
+ _Placeholder<21> _21;
+ _Placeholder<22> _22;
+ _Placeholder<23> _23;
+ _Placeholder<24> _24;
+ _Placeholder<25> _25;
+ _Placeholder<26> _26;
+ _Placeholder<27> _27;
+ _Placeholder<28> _28;
+ _Placeholder<29> _29;
+ }
+ }
+
+ /**
+ * Partial specialization of is_placeholder that provides the placeholder
+ * number for the placeholder objects defined by libstdc++.
+ */
+ template<int _Num>
+ struct is_placeholder<_Placeholder<_Num> >
+ { static const int value = _Num; };
+
+ template<int _Num>
+ const int is_placeholder<_Placeholder<_Num> >::value;
+
+ /**
+ * Stores a tuple of indices. Used by bind() to extract the elements
+ * in a tuple.
+ */
+ template<int... _Indexes>
+ struct _Index_tuple { };
+
+ /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
+ template<std::size_t _Num, typename _Tuple = _Index_tuple<> >
+ struct _Build_index_tuple;
+
+ template<std::size_t _Num, int... _Indexes>
+ struct _Build_index_tuple<_Num, _Index_tuple<_Indexes...> >
+ : _Build_index_tuple<_Num - 1,
+ _Index_tuple<_Indexes..., sizeof...(_Indexes)> >
+ {
+ };
+
+ template<int... _Indexes>
+ struct _Build_index_tuple<0, _Index_tuple<_Indexes...> >
+ {
+ typedef _Index_tuple<_Indexes...> __type;
+ };
+
+ /**
+ * Used by _Safe_tuple_element to indicate that there is no tuple
+ * element at this position.
+ */
+ struct _No_tuple_element;
+
+ /**
+ * Implementation helper for _Safe_tuple_element. This primary
+ * template handles the case where it is safe to use @c
+ * tuple_element.
+ */
+ template<int __i, typename _Tuple, bool _IsSafe>
+ struct _Safe_tuple_element_impl
+ : tuple_element<__i, _Tuple> { };
+
+ /**
+ * Implementation helper for _Safe_tuple_element. This partial
+ * specialization handles the case where it is not safe to use @c
+ * tuple_element. We just return @c _No_tuple_element.
+ */
+ template<int __i, typename _Tuple>
+ struct _Safe_tuple_element_impl<__i, _Tuple, false>
+ {
+ typedef _No_tuple_element type;
+ };
+
+ /**
+ * Like tuple_element, but returns @c _No_tuple_element when
+ * tuple_element would return an error.
+ */
+ template<int __i, typename _Tuple>
+ struct _Safe_tuple_element
+ : _Safe_tuple_element_impl<__i, _Tuple,
+ (__i >= 0 && __i < tuple_size<_Tuple>::value)>
+ {
+ };
+
+ /**
+ * Maps an argument to bind() into an actual argument to the bound
+ * function object [TR1 3.6.3/5]. Only the first parameter should
+ * be specified: the rest are used to determine among the various
+ * implementations. Note that, although this class is a function
+ * object, it isn't entirely normal because it takes only two
+ * parameters regardless of the number of parameters passed to the
+ * bind expression. The first parameter is the bound argument and
+ * the second parameter is a tuple containing references to the
+ * rest of the arguments.
+ */
+ template<typename _Arg,
+ bool _IsBindExp = is_bind_expression<_Arg>::value,
+ bool _IsPlaceholder = (is_placeholder<_Arg>::value > 0)>
+ class _Mu;
+
+ /**
+ * If the argument is reference_wrapper<_Tp>, returns the
+ * underlying reference. [TR1 3.6.3/5 bullet 1]
+ */
+ template<typename _Tp>
+ class _Mu<reference_wrapper<_Tp>, false, false>
+ {
+ public:
+ typedef _Tp& result_type;
+
+ /* Note: This won't actually work for const volatile
+ * reference_wrappers, because reference_wrapper::get() is const
+ * but not volatile-qualified. This might be a defect in the TR.
+ */
+ template<typename _CVRef, typename _Tuple>
+ result_type
+ operator()(_CVRef& __arg, const _Tuple&) const volatile
+ { return __arg.get(); }
+ };
+
+ /**
+ * If the argument is a bind expression, we invoke the underlying
+ * function object with the same cv-qualifiers as we are given and
+ * pass along all of our arguments (unwrapped). [TR1 3.6.3/5 bullet 2]
+ */
+ template<typename _Arg>
+ class _Mu<_Arg, true, false>
+ {
+ public:
+ template<typename _Signature> class result;
+
+ // Determine the result type when we pass the arguments along. This
+ // involves passing along the cv-qualifiers placed on _Mu and
+ // unwrapping the argument bundle.
+ template<typename _CVMu, typename _CVArg, typename... _Args>
+ class result<_CVMu(_CVArg, tuple<_Args...>)>
+ : public result_of<_CVArg(_Args...)> { };
+
+ template<typename _CVArg, typename... _Args>
+ typename result_of<_CVArg(_Args...)>::type
+ operator()(_CVArg& __arg,
+ const tuple<_Args...>& __tuple) const volatile
+ {
+ // Construct an index tuple and forward to __call
+ typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
+ _Indexes;
+ return this->__call(__arg, __tuple, _Indexes());
+ }
+
+ private:
+ // Invokes the underlying function object __arg by unpacking all
+ // of the arguments in the tuple.
+ template<typename _CVArg, typename... _Args, int... _Indexes>
+ typename result_of<_CVArg(_Args...)>::type
+ __call(_CVArg& __arg, const tuple<_Args...>& __tuple,
+ const _Index_tuple<_Indexes...>&) const volatile
+ {
+ return __arg(get<_Indexes>(__tuple)...);
+ }
+ };
+
+ /**
+ * If the argument is a placeholder for the Nth argument, returns
+ * a reference to the Nth argument to the bind function object.
+ * [TR1 3.6.3/5 bullet 3]
+ */
+ template<typename _Arg>
+ class _Mu<_Arg, false, true>
+ {
+ public:
+ template<typename _Signature> class result;
+
+ template<typename _CVMu, typename _CVArg, typename _Tuple>
+ class result<_CVMu(_CVArg, _Tuple)>
+ {
+ // Add a reference, if it hasn't already been done for us.
+ // This allows us to be a little bit sloppy in constructing
+ // the tuple that we pass to result_of<...>.
+ typedef typename _Safe_tuple_element<(is_placeholder<_Arg>::value
+ - 1), _Tuple>::type
+ __base_type;
+
+ public:
+ typedef typename add_lvalue_reference<__base_type>::type type;
+ };
+
+ template<typename _Tuple>
+ typename result<_Mu(_Arg, _Tuple)>::type
+ operator()(const volatile _Arg&, const _Tuple& __tuple) const volatile
+ {
+ return ::std::get<(is_placeholder<_Arg>::value - 1)>(__tuple);
+ }
+ };
+
+ /**
+ * If the argument is just a value, returns a reference to that
+ * value. The cv-qualifiers on the reference are the same as the
+ * cv-qualifiers on the _Mu object. [TR1 3.6.3/5 bullet 4]
+ */
+ template<typename _Arg>
+ class _Mu<_Arg, false, false>
+ {
+ public:
+ template<typename _Signature> struct result;
+
+ template<typename _CVMu, typename _CVArg, typename _Tuple>
+ struct result<_CVMu(_CVArg, _Tuple)>
+ {
+ typedef typename add_lvalue_reference<_CVArg>::type type;
+ };
+
+ // Pick up the cv-qualifiers of the argument
+ template<typename _CVArg, typename _Tuple>
+ _CVArg&
+ operator()(_CVArg& __arg, const _Tuple&) const volatile
+ { return __arg; }
+ };
+
+ /**
+ * Maps member pointers into instances of _Mem_fn but leaves all
+ * other function objects untouched. Used by tr1::bind(). The
+ * primary template handles the non--member-pointer case.
+ */
+ template<typename _Tp>
+ struct _Maybe_wrap_member_pointer
+ {
+ typedef _Tp type;
+
+ static const _Tp&
+ __do_wrap(const _Tp& __x)
+ { return __x; }
+ };
+
+ /**
+ * Maps member pointers into instances of _Mem_fn but leaves all
+ * other function objects untouched. Used by tr1::bind(). This
+ * partial specialization handles the member pointer case.
+ */
+ template<typename _Tp, typename _Class>
+ struct _Maybe_wrap_member_pointer<_Tp _Class::*>
+ {
+ typedef _Mem_fn<_Tp _Class::*> type;
+
+ static type
+ __do_wrap(_Tp _Class::* __pm)
+ { return type(__pm); }
+ };
+
+ /// Type of the function object returned from bind().
+ template<typename _Signature>
+ struct _Bind;
+
+ template<typename _Functor, typename... _Bound_args>
+ class _Bind<_Functor(_Bound_args...)>
+ : public _Weak_result_type<_Functor>
+ {
+ typedef _Bind __self_type;
+ typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type
+ _Bound_indexes;
+
+ _Functor _M_f;
+ tuple<_Bound_args...> _M_bound_args;
+
+ // Call unqualified
+ template<typename... _Args, int... _Indexes>
+ typename result_of<
+ _Functor(typename result_of<_Mu<_Bound_args>
+ (_Bound_args, tuple<_Args...>)>::type...)
+ >::type
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>)
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ // Call as const
+ template<typename... _Args, int... _Indexes>
+ typename result_of<
+ const _Functor(typename result_of<_Mu<_Bound_args>
+ (const _Bound_args, tuple<_Args...>)
+ >::type...)>::type
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) const
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ // Call as volatile
+ template<typename... _Args, int... _Indexes>
+ typename result_of<
+ volatile _Functor(typename result_of<_Mu<_Bound_args>
+ (volatile _Bound_args, tuple<_Args...>)
+ >::type...)>::type
+ __call(const tuple<_Args...>& __args,
+ _Index_tuple<_Indexes...>) volatile
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ // Call as const volatile
+ template<typename... _Args, int... _Indexes>
+ typename result_of<
+ const volatile _Functor(typename result_of<_Mu<_Bound_args>
+ (const volatile _Bound_args,
+ tuple<_Args...>)
+ >::type...)>::type
+ __call(const tuple<_Args...>& __args,
+ _Index_tuple<_Indexes...>) const volatile
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ public:
+ explicit _Bind(_Functor __f, _Bound_args... __bound_args)
+ : _M_f(__f), _M_bound_args(__bound_args...) { }
+
+ // Call unqualified
+ template<typename... _Args>
+ typename result_of<
+ _Functor(typename result_of<_Mu<_Bound_args>
+ (_Bound_args, tuple<_Args...>)>::type...)
+ >::type
+ operator()(_Args&... __args)
+ {
+ return this->__call(tie(__args...), _Bound_indexes());
+ }
+
+ // Call as const
+ template<typename... _Args>
+ typename result_of<
+ const _Functor(typename result_of<_Mu<_Bound_args>
+ (const _Bound_args, tuple<_Args...>)>::type...)
+ >::type
+ operator()(_Args&... __args) const
+ {
+ return this->__call(tie(__args...), _Bound_indexes());
+ }
+
+
+ // Call as volatile
+ template<typename... _Args>
+ typename result_of<
+ volatile _Functor(typename result_of<_Mu<_Bound_args>
+ (volatile _Bound_args, tuple<_Args...>)>::type...)
+ >::type
+ operator()(_Args&... __args) volatile
+ {
+ return this->__call(tie(__args...), _Bound_indexes());
+ }
+
+
+ // Call as const volatile
+ template<typename... _Args>
+ typename result_of<
+ const volatile _Functor(typename result_of<_Mu<_Bound_args>
+ (const volatile _Bound_args,
+ tuple<_Args...>)>::type...)
+ >::type
+ operator()(_Args&... __args) const volatile
+ {
+ return this->__call(tie(__args...), _Bound_indexes());
+ }
+ };
+
+ /// Type of the function object returned from bind<R>().
+ template<typename _Result, typename _Signature>
+ struct _Bind_result;
+
+ template<typename _Result, typename _Functor, typename... _Bound_args>
+ class _Bind_result<_Result, _Functor(_Bound_args...)>
+ {
+ typedef _Bind_result __self_type;
+ typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type
+ _Bound_indexes;
+
+ _Functor _M_f;
+ tuple<_Bound_args...> _M_bound_args;
+
+ // Call unqualified
+ template<typename... _Args, int... _Indexes>
+ _Result
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>)
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ // Call as const
+ template<typename... _Args, int... _Indexes>
+ _Result
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) const
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ // Call as volatile
+ template<typename... _Args, int... _Indexes>
+ _Result
+ __call(const tuple<_Args...>& __args,
+ _Index_tuple<_Indexes...>) volatile
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ // Call as const volatile
+ template<typename... _Args, int... _Indexes>
+ _Result
+ __call(const tuple<_Args...>& __args,
+ _Index_tuple<_Indexes...>) const volatile
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ public:
+ typedef _Result result_type;
+
+ explicit
+ _Bind_result(_Functor __f, _Bound_args... __bound_args)
+ : _M_f(__f), _M_bound_args(__bound_args...) { }
+
+ // Call unqualified
+ template<typename... _Args>
+ result_type
+ operator()(_Args&... __args)
+ {
+ return this->__call(tie(__args...), _Bound_indexes());
+ }
+
+ // Call as const
+ template<typename... _Args>
+ result_type
+ operator()(_Args&... __args) const
+ {
+ return this->__call(tie(__args...), _Bound_indexes());
+ }
+
+ // Call as volatile
+ template<typename... _Args>
+ result_type
+ operator()(_Args&... __args) volatile
+ {
+ return this->__call(tie(__args...), _Bound_indexes());
+ }
+
+ // Call as const volatile
+ template<typename... _Args>
+ result_type
+ operator()(_Args&... __args) const volatile
+ {
+ return this->__call(tie(__args...), _Bound_indexes());
+ }
+ };
+
+ /// Class template _Bind is always a bind expression.
+ template<typename _Signature>
+ struct is_bind_expression<_Bind<_Signature> >
+ { static const bool value = true; };
+
+ template<typename _Signature>
+ const bool is_bind_expression<_Bind<_Signature> >::value;
+
+ /// Class template _Bind_result is always a bind expression.
+ template<typename _Result, typename _Signature>
+ struct is_bind_expression<_Bind_result<_Result, _Signature> >
+ { static const bool value = true; };
+
+ template<typename _Result, typename _Signature>
+ const bool is_bind_expression<_Bind_result<_Result, _Signature> >::value;
+
+ /// bind
+ template<typename _Functor, typename... _ArgTypes>
+ inline
+ _Bind<typename _Maybe_wrap_member_pointer<_Functor>::type(_ArgTypes...)>
+ bind(_Functor __f, _ArgTypes... __args)
+ {
+ typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
+ typedef typename __maybe_type::type __functor_type;
+ typedef _Bind<__functor_type(_ArgTypes...)> __result_type;
+ return __result_type(__maybe_type::__do_wrap(__f), __args...);
+ }
+
+ template<typename _Result, typename _Functor, typename... _ArgTypes>
+ inline
+ _Bind_result<_Result,
+ typename _Maybe_wrap_member_pointer<_Functor>::type
+ (_ArgTypes...)>
+ bind(_Functor __f, _ArgTypes... __args)
+ {
+ typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
+ typedef typename __maybe_type::type __functor_type;
+ typedef _Bind_result<_Result, __functor_type(_ArgTypes...)>
+ __result_type;
+ return __result_type(__maybe_type::__do_wrap(__f), __args...);
+ }
+
+ /**
+ * @brief Exception class thrown when class template function's
+ * operator() is called with an empty target.
+ * @ingroup exceptions
+ */
+ class bad_function_call : public std::exception { };
+
+ /**
+ * The integral constant expression 0 can be converted into a
+ * pointer to this type. It is used by the function template to
+ * accept NULL pointers.
+ */
+ struct _M_clear_type;
+
+ /**
+ * Trait identifying "location-invariant" types, meaning that the
+ * address of the object (or any of its members) will not escape.
+ * Also implies a trivial copy constructor and assignment operator.
+ */
+ template<typename _Tp>
+ struct __is_location_invariant
+ : integral_constant<bool,
+ (is_pointer<_Tp>::value
+ || is_member_pointer<_Tp>::value)>
+ {
+ };
+
+ class _Undefined_class;
+
+ union _Nocopy_types
+ {
+ void* _M_object;
+ const void* _M_const_object;
+ void (*_M_function_pointer)();
+ void (_Undefined_class::*_M_member_pointer)();
+ };
+
+ union _Any_data
+ {
+ void* _M_access() { return &_M_pod_data[0]; }
+ const void* _M_access() const { return &_M_pod_data[0]; }
+
+ template<typename _Tp>
+ _Tp&
+ _M_access()
+ { return *static_cast<_Tp*>(_M_access()); }
+
+ template<typename _Tp>
+ const _Tp&
+ _M_access() const
+ { return *static_cast<const _Tp*>(_M_access()); }
+
+ _Nocopy_types _M_unused;
+ char _M_pod_data[sizeof(_Nocopy_types)];
+ };
+
+ enum _Manager_operation
+ {
+ __get_type_info,
+ __get_functor_ptr,
+ __clone_functor,
+ __destroy_functor
+ };
+
+ // Simple type wrapper that helps avoid annoying const problems
+ // when casting between void pointers and pointers-to-pointers.
+ template<typename _Tp>
+ struct _Simple_type_wrapper
+ {
+ _Simple_type_wrapper(_Tp __value) : __value(__value) { }
+
+ _Tp __value;
+ };
+
+ template<typename _Tp>
+ struct __is_location_invariant<_Simple_type_wrapper<_Tp> >
+ : __is_location_invariant<_Tp>
+ {
+ };
+
+ // Converts a reference to a function object into a callable
+ // function object.
+ template<typename _Functor>
+ inline _Functor&
+ __callable_functor(_Functor& __f)
+ { return __f; }
+
+ template<typename _Member, typename _Class>
+ inline _Mem_fn<_Member _Class::*>
+ __callable_functor(_Member _Class::* &__p)
+ { return mem_fn(__p); }
+
+ template<typename _Member, typename _Class>
+ inline _Mem_fn<_Member _Class::*>
+ __callable_functor(_Member _Class::* const &__p)
+ { return mem_fn(__p); }
+
+ template<typename _Signature>
+ class function;
+
+ /// Base class of all polymorphic function object wrappers.
+ class _Function_base
+ {
+ public:
+ static const std::size_t _M_max_size = sizeof(_Nocopy_types);
+ static const std::size_t _M_max_align = __alignof__(_Nocopy_types);
+
+ template<typename _Functor>
+ class _Base_manager
+ {
+ protected:
+ static const bool __stored_locally =
+ (__is_location_invariant<_Functor>::value
+ && sizeof(_Functor) <= _M_max_size
+ && __alignof__(_Functor) <= _M_max_align
+ && (_M_max_align % __alignof__(_Functor) == 0));
+
+ typedef integral_constant<bool, __stored_locally> _Local_storage;
+
+ // Retrieve a pointer to the function object
+ static _Functor*
+ _M_get_pointer(const _Any_data& __source)
+ {
+ const _Functor* __ptr =
+ __stored_locally? &__source._M_access<_Functor>()
+ /* have stored a pointer */ : __source._M_access<_Functor*>();
+ return const_cast<_Functor*>(__ptr);
+ }
+
+ // Clone a location-invariant function object that fits within
+ // an _Any_data structure.
+ static void
+ _M_clone(_Any_data& __dest, const _Any_data& __source, true_type)
+ {
+ new (__dest._M_access()) _Functor(__source._M_access<_Functor>());
+ }
+
+ // Clone a function object that is not location-invariant or
+ // that cannot fit into an _Any_data structure.
+ static void
+ _M_clone(_Any_data& __dest, const _Any_data& __source, false_type)
+ {
+ __dest._M_access<_Functor*>() =
+ new _Functor(*__source._M_access<_Functor*>());
+ }
+
+ // Destroying a location-invariant object may still require
+ // destruction.
+ static void
+ _M_destroy(_Any_data& __victim, true_type)
+ {
+ __victim._M_access<_Functor>().~_Functor();
+ }
+
+ // Destroying an object located on the heap.
+ static void
+ _M_destroy(_Any_data& __victim, false_type)
+ {
+ delete __victim._M_access<_Functor*>();
+ }
+
+ public:
+ static bool
+ _M_manager(_Any_data& __dest, const _Any_data& __source,
+ _Manager_operation __op)
+ {
+ switch (__op)
+ {
+#ifdef __GXX_RTTI
+ case __get_type_info:
+ __dest._M_access<const type_info*>() = &typeid(_Functor);
+ break;
+#endif
+ case __get_functor_ptr:
+ __dest._M_access<_Functor*>() = _M_get_pointer(__source);
+ break;
+
+ case __clone_functor:
+ _M_clone(__dest, __source, _Local_storage());
+ break;
+
+ case __destroy_functor:
+ _M_destroy(__dest, _Local_storage());
+ break;
+ }
+ return false;
+ }
+
+ static void
+ _M_init_functor(_Any_data& __functor, const _Functor& __f)
+ { _M_init_functor(__functor, __f, _Local_storage()); }
+
+ template<typename _Signature>
+ static bool
+ _M_not_empty_function(const function<_Signature>& __f)
+ { return static_cast<bool>(__f); }
+
+ template<typename _Tp>
+ static bool
+ _M_not_empty_function(const _Tp*& __fp)
+ { return __fp; }
+
+ template<typename _Class, typename _Tp>
+ static bool
+ _M_not_empty_function(_Tp _Class::* const& __mp)
+ { return __mp; }
+
+ template<typename _Tp>
+ static bool
+ _M_not_empty_function(const _Tp&)
+ { return true; }
+
+ private:
+ static void
+ _M_init_functor(_Any_data& __functor, const _Functor& __f, true_type)
+ { new (__functor._M_access()) _Functor(__f); }
+
+ static void
+ _M_init_functor(_Any_data& __functor, const _Functor& __f, false_type)
+ { __functor._M_access<_Functor*>() = new _Functor(__f); }
+ };
+
+ template<typename _Functor>
+ class _Ref_manager : public _Base_manager<_Functor*>
+ {
+ typedef _Function_base::_Base_manager<_Functor*> _Base;
+
+ public:
+ static bool
+ _M_manager(_Any_data& __dest, const _Any_data& __source,
+ _Manager_operation __op)
+ {
+ switch (__op)
+ {
+#ifdef __GXX_RTTI
+ case __get_type_info:
+ __dest._M_access<const type_info*>() = &typeid(_Functor);
+ break;
#endif
+ case __get_functor_ptr:
+ __dest._M_access<_Functor*>() = *_Base::_M_get_pointer(__source);
+ return is_const<_Functor>::value;
+ break;
+
+ default:
+ _Base::_M_manager(__dest, __source, __op);
+ }
+ return false;
+ }
+
+ static void
+ _M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f)
+ {
+ // TBD: Use address_of function instead.
+ _Base::_M_init_functor(__functor, &__f.get());
+ }
+ };
+
+ _Function_base() : _M_manager(0) { }
+
+ ~_Function_base()
+ {
+ if (_M_manager)
+ _M_manager(_M_functor, _M_functor, __destroy_functor);
+ }
+
+
+ bool _M_empty() const { return !_M_manager; }
+
+ typedef bool (*_Manager_type)(_Any_data&, const _Any_data&,
+ _Manager_operation);
+
+ _Any_data _M_functor;
+ _Manager_type _M_manager;
+ };
+
+ template<typename _Signature, typename _Functor>
+ class _Function_handler;
+
+ template<typename _Res, typename _Functor, typename... _ArgTypes>
+ class _Function_handler<_Res(_ArgTypes...), _Functor>
+ : public _Function_base::_Base_manager<_Functor>
+ {
+ typedef _Function_base::_Base_manager<_Functor> _Base;
+
+ public:
+ static _Res
+ _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
+ {
+ return (*_Base::_M_get_pointer(__functor))(
+ std::forward<_ArgTypes>(__args)...);
+ }
+ };
+
+ template<typename _Functor, typename... _ArgTypes>
+ class _Function_handler<void(_ArgTypes...), _Functor>
+ : public _Function_base::_Base_manager<_Functor>
+ {
+ typedef _Function_base::_Base_manager<_Functor> _Base;
+
+ public:
+ static void
+ _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
+ {
+ (*_Base::_M_get_pointer(__functor))(
+ std::forward<_ArgTypes>(__args)...);
+ }
+ };
+
+ template<typename _Res, typename _Functor, typename... _ArgTypes>
+ class _Function_handler<_Res(_ArgTypes...), reference_wrapper<_Functor> >
+ : public _Function_base::_Ref_manager<_Functor>
+ {
+ typedef _Function_base::_Ref_manager<_Functor> _Base;
+
+ public:
+ static _Res
+ _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
+ {
+ return __callable_functor(**_Base::_M_get_pointer(__functor))(
+ std::forward<_ArgTypes>(__args)...);
+ }
+ };
+
+ template<typename _Functor, typename... _ArgTypes>
+ class _Function_handler<void(_ArgTypes...), reference_wrapper<_Functor> >
+ : public _Function_base::_Ref_manager<_Functor>
+ {
+ typedef _Function_base::_Ref_manager<_Functor> _Base;
+
+ public:
+ static void
+ _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
+ {
+ __callable_functor(**_Base::_M_get_pointer(__functor))(
+ std::forward<_ArgTypes>(__args)...);
+ }
+ };
+
+ template<typename _Class, typename _Member, typename _Res,
+ typename... _ArgTypes>
+ class _Function_handler<_Res(_ArgTypes...), _Member _Class::*>
+ : public _Function_handler<void(_ArgTypes...), _Member _Class::*>
+ {
+ typedef _Function_handler<void(_ArgTypes...), _Member _Class::*>
+ _Base;
+
+ public:
+ static _Res
+ _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
+ {
+ return mem_fn(_Base::_M_get_pointer(__functor)->__value)(
+ std::forward<_ArgTypes>(__args)...);
+ }
+ };
+
+ template<typename _Class, typename _Member, typename... _ArgTypes>
+ class _Function_handler<void(_ArgTypes...), _Member _Class::*>
+ : public _Function_base::_Base_manager<
+ _Simple_type_wrapper< _Member _Class::* > >
+ {
+ typedef _Member _Class::* _Functor;
+ typedef _Simple_type_wrapper<_Functor> _Wrapper;
+ typedef _Function_base::_Base_manager<_Wrapper> _Base;
+
+ public:
+ static bool
+ _M_manager(_Any_data& __dest, const _Any_data& __source,
+ _Manager_operation __op)
+ {
+ switch (__op)
+ {
+#ifdef __GXX_RTTI
+ case __get_type_info:
+ __dest._M_access<const type_info*>() = &typeid(_Functor);
+ break;
+#endif
+ case __get_functor_ptr:
+ __dest._M_access<_Functor*>() =
+ &_Base::_M_get_pointer(__source)->__value;
+ break;
+
+ default:
+ _Base::_M_manager(__dest, __source, __op);
+ }
+ return false;
+ }
+
+ static void
+ _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
+ {
+ mem_fn(_Base::_M_get_pointer(__functor)->__value)(
+ std::forward<_ArgTypes>(__args)...);
+ }
+ };
+
+ /// class function
+ template<typename _Res, typename... _ArgTypes>
+ class function<_Res(_ArgTypes...)>
+ : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,
+ private _Function_base
+ {
+ typedef _Res _Signature_type(_ArgTypes...);
+
+ struct _Useless { };
+
+ public:
+ typedef _Res result_type;
+
+ // [3.7.2.1] construct/copy/destroy
+
+ /**
+ * @brief Default construct creates an empty function call wrapper.
+ * @post @c !(bool)*this
+ */
+ explicit
+ function() : _Function_base() { }
+
+ /**
+ * @brief Default construct creates an empty function call wrapper.
+ * @post @c !(bool)*this
+ */
+ function(_M_clear_type*) : _Function_base() { }
+
+ /**
+ * @brief %Function copy constructor.
+ * @param x A %function object with identical call signature.
+ * @post @c (bool)*this == (bool)x
+ *
+ * The newly-created %function contains a copy of the target of @a
+ * x (if it has one).
+ */
+ function(const function& __x);
+
+ /**
+ * @brief %Function move constructor.
+ * @param x A %function object rvalue with identical call signature.
+ *
+ * The newly-created %function contains the target of @a x
+ * (if it has one).
+ */
+ function(function&& __x) : _Function_base()
+ {
+ __x.swap(*this);
+ }
+
+ // TODO: needs allocator_arg_t
+
+ /**
+ * @brief Builds a %function that targets a copy of the incoming
+ * function object.
+ * @param f A %function object that is callable with parameters of
+ * type @c T1, @c T2, ..., @c TN and returns a value convertible
+ * to @c Res.
+ *
+ * The newly-created %function object will target a copy of @a
+ * f. If @a f is @c reference_wrapper<F>, then this function
+ * object will contain a reference to the function object @c
+ * f.get(). If @a f is a NULL function pointer or NULL
+ * pointer-to-member, the newly-created object will be empty.
+ *
+ * If @a f is a non-NULL function pointer or an object of type @c
+ * reference_wrapper<F>, this function will not throw.
+ */
+ template<typename _Functor>
+ function(_Functor __f,
+ typename __gnu_cxx::__enable_if<
+ !is_integral<_Functor>::value, _Useless>::__type
+ = _Useless());
+
+ /**
+ * @brief %Function assignment operator.
+ * @param x A %function with identical call signature.
+ * @post @c (bool)*this == (bool)x
+ * @returns @c *this
+ *
+ * The target of @a x is copied to @c *this. If @a x has no
+ * target, then @c *this will be empty.
+ *
+ * If @a x targets a function pointer or a reference to a function
+ * object, then this operation will not throw an %exception.
+ */
+ function&
+ operator=(const function& __x)
+ {
+ function(__x).swap(*this);
+ return *this;
+ }
+
+ /**
+ * @brief %Function move-assignment operator.
+ * @param x A %function rvalue with identical call signature.
+ * @returns @c *this
+ *
+ * The target of @a x is moved to @c *this. If @a x has no
+ * target, then @c *this will be empty.
+ *
+ * If @a x targets a function pointer or a reference to a function
+ * object, then this operation will not throw an %exception.
+ */
+ function&
+ operator=(function&& __x)
+ {
+ function(std::move(__x)).swap(*this);
+ return *this;
+ }
+
+ /**
+ * @brief %Function assignment to zero.
+ * @post @c !(bool)*this
+ * @returns @c *this
+ *
+ * The target of @c *this is deallocated, leaving it empty.
+ */
+ function&
+ operator=(_M_clear_type*)
+ {
+ if (_M_manager)
+ {
+ _M_manager(_M_functor, _M_functor, __destroy_functor);
+ _M_manager = 0;
+ _M_invoker = 0;
+ }
+ return *this;
+ }
+
+ /**
+ * @brief %Function assignment to a new target.
+ * @param f A %function object that is callable with parameters of
+ * type @c T1, @c T2, ..., @c TN and returns a value convertible
+ * to @c Res.
+ * @return @c *this
+ *
+ * This %function object wrapper will target a copy of @a
+ * f. If @a f is @c reference_wrapper<F>, then this function
+ * object will contain a reference to the function object @c
+ * f.get(). If @a f is a NULL function pointer or NULL
+ * pointer-to-member, @c this object will be empty.
+ *
+ * If @a f is a non-NULL function pointer or an object of type @c
+ * reference_wrapper<F>, this function will not throw.
+ */
+ template<typename _Functor>
+ typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value,
+ function&>::__type
+ operator=(_Functor __f)
+ {
+ function(__f).swap(*this);
+ return *this;
+ }
+
+ /// @overload
+ template<typename _Functor>
+ typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value,
+ function&>::__type
+ operator=(reference_wrapper<_Functor> __f)
+ {
+ function(__f).swap(*this);
+ return *this;
+ }
+
+ // [3.7.2.2] function modifiers
+
+ /**
+ * @brief Swap the targets of two %function objects.
+ * @param f A %function with identical call signature.
+ *
+ * Swap the targets of @c this function object and @a f. This
+ * function will not throw an %exception.
+ */
+ void swap(function& __x)
+ {
+ _Any_data __old_functor = _M_functor;
+ _M_functor = __x._M_functor;
+ __x._M_functor = __old_functor;
+ _Manager_type __old_manager = _M_manager;
+ _M_manager = __x._M_manager;
+ __x._M_manager = __old_manager;
+ _Invoker_type __old_invoker = _M_invoker;
+ _M_invoker = __x._M_invoker;
+ __x._M_invoker = __old_invoker;
+ }
+
+ // TODO: needs allocator_arg_t
+ /*
+ template<typename _Functor, typename _Alloc>
+ void
+ assign(_Functor __f, const _Alloc& __a)
+ {
+ function(__f, __a).swap(*this);
+ }
+ */
+
+ // [3.7.2.3] function capacity
+
+ /**
+ * @brief Determine if the %function wrapper has a target.
+ *
+ * @return @c true when this %function object contains a target,
+ * or @c false when it is empty.
+ *
+ * This function will not throw an %exception.
+ */
+ explicit operator bool() const
+ { return !_M_empty(); }
+
+ // [3.7.2.4] function invocation
+
+ /**
+ * @brief Invokes the function targeted by @c *this.
+ * @returns the result of the target.
+ * @throws bad_function_call when @c !(bool)*this
+ *
+ * The function call operator invokes the target function object
+ * stored by @c this.
+ */
+ _Res operator()(_ArgTypes... __args) const;
+
+#ifdef __GXX_RTTI
+ // [3.7.2.5] function target access
+ /**
+ * @brief Determine the type of the target of this function object
+ * wrapper.
+ *
+ * @returns the type identifier of the target function object, or
+ * @c typeid(void) if @c !(bool)*this.
+ *
+ * This function will not throw an %exception.
+ */
+ const type_info& target_type() const;
+
+ /**
+ * @brief Access the stored target function object.
+ *
+ * @return Returns a pointer to the stored target function object,
+ * if @c typeid(Functor).equals(target_type()); otherwise, a NULL
+ * pointer.
+ *
+ * This function will not throw an %exception.
+ */
+ template<typename _Functor> _Functor* target();
+
+ /// @overload
+ template<typename _Functor> const _Functor* target() const;
+#endif
+
+ // deleted overloads
+ template<typename _Res2, typename... _ArgTypes2>
+ void operator==(const function<_Res2(_ArgTypes2...)>&) const = delete;
+ template<typename _Res2, typename... _ArgTypes2>
+ void operator!=(const function<_Res2(_ArgTypes2...)>&) const = delete;
+
+ private:
+ typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...);
+ _Invoker_type _M_invoker;
+ };
+
+ template<typename _Res, typename... _ArgTypes>
+ function<_Res(_ArgTypes...)>::
+ function(const function& __x)
+ : _Function_base()
+ {
+ if (static_cast<bool>(__x))
+ {
+ _M_invoker = __x._M_invoker;
+ _M_manager = __x._M_manager;
+ __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
+ }
+ }
+
+ template<typename _Res, typename... _ArgTypes>
+ template<typename _Functor>
+ function<_Res(_ArgTypes...)>::
+ function(_Functor __f,
+ typename __gnu_cxx::__enable_if<
+ !is_integral<_Functor>::value, _Useless>::__type)
+ : _Function_base()
+ {
+ typedef _Function_handler<_Signature_type, _Functor> _My_handler;
+
+ if (_My_handler::_M_not_empty_function(__f))
+ {
+ _M_invoker = &_My_handler::_M_invoke;
+ _M_manager = &_My_handler::_M_manager;
+ _My_handler::_M_init_functor(_M_functor, __f);
+ }
+ }
+
+ template<typename _Res, typename... _ArgTypes>
+ _Res
+ function<_Res(_ArgTypes...)>::
+ operator()(_ArgTypes... __args) const
+ {
+ if (_M_empty())
+ {
+#if __EXCEPTIONS
+ throw bad_function_call();
+#else
+ __builtin_abort();
+#endif
+ }
+ return _M_invoker(_M_functor, std::forward<_ArgTypes>(__args)...);
+ }
+
+#ifdef __GXX_RTTI
+ template<typename _Res, typename... _ArgTypes>
+ const type_info&
+ function<_Res(_ArgTypes...)>::
+ target_type() const
+ {
+ if (_M_manager)
+ {
+ _Any_data __typeinfo_result;
+ _M_manager(__typeinfo_result, _M_functor, __get_type_info);
+ return *__typeinfo_result._M_access<const type_info*>();
+ }
+ else
+ return typeid(void);
+ }
+
+ template<typename _Res, typename... _ArgTypes>
+ template<typename _Functor>
+ _Functor*
+ function<_Res(_ArgTypes...)>::
+ target()
+ {
+ if (typeid(_Functor) == target_type() && _M_manager)
+ {
+ _Any_data __ptr;
+ if (_M_manager(__ptr, _M_functor, __get_functor_ptr)
+ && !is_const<_Functor>::value)
+ return 0;
+ else
+ return __ptr._M_access<_Functor*>();
+ }
+ else
+ return 0;
+ }
+
+ template<typename _Res, typename... _ArgTypes>
+ template<typename _Functor>
+ const _Functor*
+ function<_Res(_ArgTypes...)>::
+ target() const
+ {
+ if (typeid(_Functor) == target_type() && _M_manager)
+ {
+ _Any_data __ptr;
+ _M_manager(__ptr, _M_functor, __get_functor_ptr);
+ return __ptr._M_access<const _Functor*>();
+ }
+ else
+ return 0;
+ }
+#endif
+
+ // [20.7.15.2.6] null pointer comparisons
+
+ /**
+ * @brief Compares a polymorphic function object wrapper against 0
+ * (the NULL pointer).
+ * @returns @c true if the wrapper has no target, @c false otherwise
+ *
+ * This function will not throw an %exception.
+ */
+ template<typename _Res, typename... _Args>
+ inline bool
+ operator==(const function<_Res(_Args...)>& __f, _M_clear_type*)
+ { return !static_cast<bool>(__f); }
+
+ /// @overload
+ template<typename _Res, typename... _Args>
+ inline bool
+ operator==(_M_clear_type*, const function<_Res(_Args...)>& __f)
+ { return !static_cast<bool>(__f); }
+
+ /**
+ * @brief Compares a polymorphic function object wrapper against 0
+ * (the NULL pointer).
+ * @returns @c false if the wrapper has no target, @c true otherwise
+ *
+ * This function will not throw an %exception.
+ */
+ template<typename _Res, typename... _Args>
+ inline bool
+ operator!=(const function<_Res(_Args...)>& __f, _M_clear_type*)
+ { return static_cast<bool>(__f); }
+
+ /// @overload
+ template<typename _Res, typename... _Args>
+ inline bool
+ operator!=(_M_clear_type*, const function<_Res(_Args...)>& __f)
+ { return static_cast<bool>(__f); }
+
+ // [20.7.15.2.7] specialized algorithms
+
+ /**
+ * @brief Swap the targets of two polymorphic function object wrappers.
+ *
+ * This function will not throw an %exception.
+ */
+ template<typename _Res, typename... _Args>
+ inline void
+ swap(function<_Res(_Args...)>& __x, function<_Res(_Args...)>& __y)
+ { __x.swap(__y); }
+}
+
+#endif // __GXX_EXPERIMENTAL_CXX0X__
#endif // _GLIBCXX_FUNCTIONAL
diff --git a/libstdc++-v3/include/tr1/functional b/libstdc++-v3/include/tr1/functional
index 3deaa5ea56d..4825509aed7 100644
--- a/libstdc++-v3/include/tr1/functional
+++ b/libstdc++-v3/include/tr1/functional
@@ -31,10 +31,6 @@
#pragma GCC system_header
-#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
-# error TR1 header cannot be included from C++0x header
-#endif
-
#include <bits/c++config.h>
#include <bits/stl_function.h>
@@ -46,18 +42,2102 @@
#include <tr1/functional_hash.h>
#include <ext/type_traits.h>
-#if defined(_GLIBCXX_INCLUDE_AS_TR1)
-# include <tr1_impl/functional>
+namespace std
+{
+namespace tr1
+{
+ template<typename _MemberPointer>
+ class _Mem_fn;
+
+ /**
+ * Actual implementation of _Has_result_type, which uses SFINAE to
+ * determine if the type _Tp has a publicly-accessible member type
+ * result_type.
+ */
+ template<typename _Tp>
+ class _Has_result_type_helper : __sfinae_types
+ {
+ template<typename _Up>
+ struct _Wrap_type
+ { };
+
+ template<typename _Up>
+ static __one __test(_Wrap_type<typename _Up::result_type>*);
+
+ template<typename _Up>
+ static __two __test(...);
+
+ public:
+ static const bool value = sizeof(__test<_Tp>(0)) == 1;
+ };
+
+ template<typename _Tp>
+ struct _Has_result_type
+ : integral_constant<bool,
+ _Has_result_type_helper<typename remove_cv<_Tp>::type>::value>
+ { };
+
+ /**
+ *
+ */
+ /// If we have found a result_type, extract it.
+ template<bool _Has_result_type, typename _Functor>
+ struct _Maybe_get_result_type
+ { };
+
+ template<typename _Functor>
+ struct _Maybe_get_result_type<true, _Functor>
+ {
+ typedef typename _Functor::result_type result_type;
+ };
+
+ /**
+ * Base class for any function object that has a weak result type, as
+ * defined in 3.3/3 of TR1.
+ */
+ template<typename _Functor>
+ struct _Weak_result_type_impl
+ : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor>
+ {
+ };
+
+ /// Retrieve the result type for a function type.
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(_ArgTypes...)>
+ {
+ typedef _Res result_type;
+ };
+
+ /// Retrieve the result type for a function reference.
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(&)(_ArgTypes...)>
+ {
+ typedef _Res result_type;
+ };
+
+ /// Retrieve the result type for a function pointer.
+ template<typename _Res, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res(*)(_ArgTypes...)>
+ {
+ typedef _Res result_type;
+ };
+
+ /// Retrieve result type for a member function pointer.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)>
+ {
+ typedef _Res result_type;
+ };
+
+ /// Retrieve result type for a const member function pointer.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) const>
+ {
+ typedef _Res result_type;
+ };
+
+ /// Retrieve result type for a volatile member function pointer.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) volatile>
+ {
+ typedef _Res result_type;
+ };
+
+ /// Retrieve result type for a const volatile member function pointer.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)const volatile>
+ {
+ typedef _Res result_type;
+ };
+
+ /**
+ * Strip top-level cv-qualifiers from the function object and let
+ * _Weak_result_type_impl perform the real work.
+ */
+ template<typename _Functor>
+ struct _Weak_result_type
+ : _Weak_result_type_impl<typename remove_cv<_Functor>::type>
+ {
+ };
+
+ template<typename _Signature>
+ class result_of;
+
+ /**
+ * Actual implementation of result_of. When _Has_result_type is
+ * true, gets its result from _Weak_result_type. Otherwise, uses
+ * the function object's member template result to extract the
+ * result type.
+ */
+ template<bool _Has_result_type, typename _Signature>
+ struct _Result_of_impl;
+
+ // Handle member data pointers using _Mem_fn's logic
+ template<typename _Res, typename _Class, typename _T1>
+ struct _Result_of_impl<false, _Res _Class::*(_T1)>
+ {
+ typedef typename _Mem_fn<_Res _Class::*>
+ ::template _Result_type<_T1>::type type;
+ };
+
+ /**
+ * Determine whether we can determine a result type from @c Functor
+ * alone.
+ */
+ template<typename _Functor, typename... _ArgTypes>
+ class result_of<_Functor(_ArgTypes...)>
+ : public _Result_of_impl<
+ _Has_result_type<_Weak_result_type<_Functor> >::value,
+ _Functor(_ArgTypes...)>
+ {
+ };
+
+ /// We already know the result type for @c Functor; use it.
+ template<typename _Functor, typename... _ArgTypes>
+ struct _Result_of_impl<true, _Functor(_ArgTypes...)>
+ {
+ typedef typename _Weak_result_type<_Functor>::result_type type;
+ };
+
+ /**
+ * We need to compute the result type for this invocation the hard
+ * way.
+ */
+ template<typename _Functor, typename... _ArgTypes>
+ struct _Result_of_impl<false, _Functor(_ArgTypes...)>
+ {
+ typedef typename _Functor
+ ::template result<_Functor(_ArgTypes...)>::type type;
+ };
+
+ /**
+ * It is unsafe to access ::result when there are zero arguments, so we
+ * return @c void instead.
+ */
+ template<typename _Functor>
+ struct _Result_of_impl<false, _Functor()>
+ {
+ typedef void type;
+ };
+
+ /// Determines if the type _Tp derives from unary_function.
+ template<typename _Tp>
+ struct _Derives_from_unary_function : __sfinae_types
+ {
+ private:
+ template<typename _T1, typename _Res>
+ static __one __test(const volatile unary_function<_T1, _Res>*);
+
+ // It's tempting to change "..." to const volatile void*, but
+ // that fails when _Tp is a function type.
+ static __two __test(...);
+
+ public:
+ static const bool value = sizeof(__test((_Tp*)0)) == 1;
+ };
+
+ /// Determines if the type _Tp derives from binary_function.
+ template<typename _Tp>
+ struct _Derives_from_binary_function : __sfinae_types
+ {
+ private:
+ template<typename _T1, typename _T2, typename _Res>
+ static __one __test(const volatile binary_function<_T1, _T2, _Res>*);
+
+ // It's tempting to change "..." to const volatile void*, but
+ // that fails when _Tp is a function type.
+ static __two __test(...);
+
+ public:
+ static const bool value = sizeof(__test((_Tp*)0)) == 1;
+ };
+
+ /// Turns a function type into a function pointer type
+ template<typename _Tp, bool _IsFunctionType = is_function<_Tp>::value>
+ struct _Function_to_function_pointer
+ {
+ typedef _Tp type;
+ };
+
+ template<typename _Tp>
+ struct _Function_to_function_pointer<_Tp, true>
+ {
+ typedef _Tp* type;
+ };
+
+ /**
+ * Invoke a function object, which may be either a member pointer or a
+ * function object. The first parameter will tell which.
+ */
+ template<typename _Functor, typename... _Args>
+ inline
+ typename __gnu_cxx::__enable_if<
+ (!is_member_pointer<_Functor>::value
+ && !is_function<_Functor>::value
+ && !is_function<typename remove_pointer<_Functor>::type>::value),
+ typename result_of<_Functor(_Args...)>::type
+ >::__type
+ __invoke(_Functor& __f, _Args&... __args)
+ {
+ return __f(__args...);
+ }
+
+ template<typename _Functor, typename... _Args>
+ inline
+ typename __gnu_cxx::__enable_if<
+ (is_member_pointer<_Functor>::value
+ && !is_function<_Functor>::value
+ && !is_function<typename remove_pointer<_Functor>::type>::value),
+ typename result_of<_Functor(_Args...)>::type
+ >::__type
+ __invoke(_Functor& __f, _Args&... __args)
+ {
+ return mem_fn(__f)(__args...);
+ }
+
+ // To pick up function references (that will become function pointers)
+ template<typename _Functor, typename... _Args>
+ inline
+ typename __gnu_cxx::__enable_if<
+ (is_pointer<_Functor>::value
+ && is_function<typename remove_pointer<_Functor>::type>::value),
+ typename result_of<_Functor(_Args...)>::type
+ >::__type
+ __invoke(_Functor __f, _Args&... __args)
+ {
+ return __f(__args...);
+ }
+
+ /**
+ * Knowing which of unary_function and binary_function _Tp derives
+ * from, derives from the same and ensures that reference_wrapper
+ * will have a weak result type. See cases below.
+ */
+ template<bool _Unary, bool _Binary, typename _Tp>
+ struct _Reference_wrapper_base_impl;
+
+ // Not a unary_function or binary_function, so try a weak result type.
+ template<typename _Tp>
+ struct _Reference_wrapper_base_impl<false, false, _Tp>
+ : _Weak_result_type<_Tp>
+ { };
+
+ // unary_function but not binary_function
+ template<typename _Tp>
+ struct _Reference_wrapper_base_impl<true, false, _Tp>
+ : unary_function<typename _Tp::argument_type,
+ typename _Tp::result_type>
+ { };
+
+ // binary_function but not unary_function
+ template<typename _Tp>
+ struct _Reference_wrapper_base_impl<false, true, _Tp>
+ : binary_function<typename _Tp::first_argument_type,
+ typename _Tp::second_argument_type,
+ typename _Tp::result_type>
+ { };
+
+ // Both unary_function and binary_function. Import result_type to
+ // avoid conflicts.
+ template<typename _Tp>
+ struct _Reference_wrapper_base_impl<true, true, _Tp>
+ : unary_function<typename _Tp::argument_type,
+ typename _Tp::result_type>,
+ binary_function<typename _Tp::first_argument_type,
+ typename _Tp::second_argument_type,
+ typename _Tp::result_type>
+ {
+ typedef typename _Tp::result_type result_type;
+ };
+
+ /**
+ * Derives from unary_function or binary_function when it
+ * can. Specializations handle all of the easy cases. The primary
+ * template determines what to do with a class type, which may
+ * derive from both unary_function and binary_function.
+ */
+ template<typename _Tp>
+ struct _Reference_wrapper_base
+ : _Reference_wrapper_base_impl<
+ _Derives_from_unary_function<_Tp>::value,
+ _Derives_from_binary_function<_Tp>::value,
+ _Tp>
+ { };
+
+ // - a function type (unary)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res(_T1)>
+ : unary_function<_T1, _Res>
+ { };
+
+ // - a function type (binary)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res(_T1, _T2)>
+ : binary_function<_T1, _T2, _Res>
+ { };
+
+ // - a function pointer type (unary)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res(*)(_T1)>
+ : unary_function<_T1, _Res>
+ { };
+
+ // - a function pointer type (binary)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res(*)(_T1, _T2)>
+ : binary_function<_T1, _T2, _Res>
+ { };
+
+ // - a pointer to member function type (unary, no qualifiers)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res (_T1::*)()>
+ : unary_function<_T1*, _Res>
+ { };
+
+ // - a pointer to member function type (binary, no qualifiers)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2)>
+ : binary_function<_T1*, _T2, _Res>
+ { };
+
+ // - a pointer to member function type (unary, const)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res (_T1::*)() const>
+ : unary_function<const _T1*, _Res>
+ { };
+
+ // - a pointer to member function type (binary, const)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const>
+ : binary_function<const _T1*, _T2, _Res>
+ { };
+
+ // - a pointer to member function type (unary, volatile)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res (_T1::*)() volatile>
+ : unary_function<volatile _T1*, _Res>
+ { };
+
+ // - a pointer to member function type (binary, volatile)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) volatile>
+ : binary_function<volatile _T1*, _T2, _Res>
+ { };
+
+ // - a pointer to member function type (unary, const volatile)
+ template<typename _Res, typename _T1>
+ struct _Reference_wrapper_base<_Res (_T1::*)() const volatile>
+ : unary_function<const volatile _T1*, _Res>
+ { };
+
+ // - a pointer to member function type (binary, const volatile)
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const volatile>
+ : binary_function<const volatile _T1*, _T2, _Res>
+ { };
+
+ /// reference_wrapper
+ template<typename _Tp>
+ class reference_wrapper
+ : public _Reference_wrapper_base<typename remove_cv<_Tp>::type>
+ {
+ // If _Tp is a function type, we can't form result_of<_Tp(...)>,
+ // so turn it into a function pointer type.
+ typedef typename _Function_to_function_pointer<_Tp>::type
+ _M_func_type;
+
+ _Tp* _M_data;
+ public:
+ typedef _Tp type;
+
+ explicit
+ reference_wrapper(_Tp& __indata): _M_data(&__indata)
+ { }
+
+ reference_wrapper(const reference_wrapper<_Tp>& __inref):
+ _M_data(__inref._M_data)
+ { }
+
+ reference_wrapper&
+ operator=(const reference_wrapper<_Tp>& __inref)
+ {
+ _M_data = __inref._M_data;
+ return *this;
+ }
+
+ operator _Tp&() const
+ { return this->get(); }
+
+ _Tp&
+ get() const
+ { return *_M_data; }
+
+ template<typename... _Args>
+ typename result_of<_M_func_type(_Args...)>::type
+ operator()(_Args&... __args) const
+ {
+ return __invoke(get(), __args...);
+ }
+ };
+
+
+ // Denotes a reference should be taken to a variable.
+ template<typename _Tp>
+ inline reference_wrapper<_Tp>
+ ref(_Tp& __t)
+ { return reference_wrapper<_Tp>(__t); }
+
+ // Denotes a const reference should be taken to a variable.
+ template<typename _Tp>
+ inline reference_wrapper<const _Tp>
+ cref(const _Tp& __t)
+ { return reference_wrapper<const _Tp>(__t); }
+
+ template<typename _Tp>
+ inline reference_wrapper<_Tp>
+ ref(reference_wrapper<_Tp> __t)
+ { return ref(__t.get()); }
+
+ template<typename _Tp>
+ inline reference_wrapper<const _Tp>
+ cref(reference_wrapper<_Tp> __t)
+ { return cref(__t.get()); }
+
+ template<typename _Tp, bool>
+ struct _Mem_fn_const_or_non
+ {
+ typedef const _Tp& type;
+ };
+
+ template<typename _Tp>
+ struct _Mem_fn_const_or_non<_Tp, false>
+ {
+ typedef _Tp& type;
+ };
+
+ /**
+ * Derives from @c unary_function or @c binary_function, or perhaps
+ * nothing, depending on the number of arguments provided. The
+ * primary template is the basis case, which derives nothing.
+ */
+ template<typename _Res, typename... _ArgTypes>
+ struct _Maybe_unary_or_binary_function { };
+
+ /// Derives from @c unary_function, as appropriate.
+ template<typename _Res, typename _T1>
+ struct _Maybe_unary_or_binary_function<_Res, _T1>
+ : std::unary_function<_T1, _Res> { };
+
+ /// Derives from @c binary_function, as appropriate.
+ template<typename _Res, typename _T1, typename _T2>
+ struct _Maybe_unary_or_binary_function<_Res, _T1, _T2>
+ : std::binary_function<_T1, _T2, _Res> { };
+
+ /// Implementation of @c mem_fn for member function pointers.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ class _Mem_fn<_Res (_Class::*)(_ArgTypes...)>
+ : public _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...>
+ {
+ typedef _Res (_Class::*_Functor)(_ArgTypes...);
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __object, const volatile _Class *,
+ _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
+ { return ((*__ptr).*__pmf)(__args...); }
+
+ public:
+ typedef _Res result_type;
+
+ explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+
+ // Handle objects
+ _Res
+ operator()(_Class& __object, _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ // Handle pointers
+ _Res
+ operator()(_Class* __object, _ArgTypes... __args) const
+ { return (__object->*__pmf)(__args...); }
+
+ // Handle smart pointers, references and pointers to derived
+ template<typename _Tp>
+ _Res
+ operator()(_Tp& __object, _ArgTypes... __args) const
+ { return _M_call(__object, &__object, __args...); }
+
+ private:
+ _Functor __pmf;
+ };
+
+ /// Implementation of @c mem_fn for const member function pointers.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const>
+ : public _Maybe_unary_or_binary_function<_Res, const _Class*,
+ _ArgTypes...>
+ {
+ typedef _Res (_Class::*_Functor)(_ArgTypes...) const;
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __object, const volatile _Class *,
+ _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
+ { return ((*__ptr).*__pmf)(__args...); }
+
+ public:
+ typedef _Res result_type;
+
+ explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+
+ // Handle objects
+ _Res
+ operator()(const _Class& __object, _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ // Handle pointers
+ _Res
+ operator()(const _Class* __object, _ArgTypes... __args) const
+ { return (__object->*__pmf)(__args...); }
+
+ // Handle smart pointers, references and pointers to derived
+ template<typename _Tp>
+ _Res operator()(_Tp& __object, _ArgTypes... __args) const
+ { return _M_call(__object, &__object, __args...); }
+
+ private:
+ _Functor __pmf;
+ };
+
+ /// Implementation of @c mem_fn for volatile member function pointers.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ class _Mem_fn<_Res (_Class::*)(_ArgTypes...) volatile>
+ : public _Maybe_unary_or_binary_function<_Res, volatile _Class*,
+ _ArgTypes...>
+ {
+ typedef _Res (_Class::*_Functor)(_ArgTypes...) volatile;
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __object, const volatile _Class *,
+ _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
+ { return ((*__ptr).*__pmf)(__args...); }
+
+ public:
+ typedef _Res result_type;
+
+ explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+
+ // Handle objects
+ _Res
+ operator()(volatile _Class& __object, _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ // Handle pointers
+ _Res
+ operator()(volatile _Class* __object, _ArgTypes... __args) const
+ { return (__object->*__pmf)(__args...); }
+
+ // Handle smart pointers, references and pointers to derived
+ template<typename _Tp>
+ _Res
+ operator()(_Tp& __object, _ArgTypes... __args) const
+ { return _M_call(__object, &__object, __args...); }
+
+ private:
+ _Functor __pmf;
+ };
+
+ /// Implementation of @c mem_fn for const volatile member function pointers.
+ template<typename _Res, typename _Class, typename... _ArgTypes>
+ class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const volatile>
+ : public _Maybe_unary_or_binary_function<_Res, const volatile _Class*,
+ _ArgTypes...>
+ {
+ typedef _Res (_Class::*_Functor)(_ArgTypes...) const volatile;
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __object, const volatile _Class *,
+ _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ template<typename _Tp>
+ _Res
+ _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
+ { return ((*__ptr).*__pmf)(__args...); }
+
+ public:
+ typedef _Res result_type;
+
+ explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
+
+ // Handle objects
+ _Res
+ operator()(const volatile _Class& __object, _ArgTypes... __args) const
+ { return (__object.*__pmf)(__args...); }
+
+ // Handle pointers
+ _Res
+ operator()(const volatile _Class* __object, _ArgTypes... __args) const
+ { return (__object->*__pmf)(__args...); }
+
+ // Handle smart pointers, references and pointers to derived
+ template<typename _Tp>
+ _Res operator()(_Tp& __object, _ArgTypes... __args) const
+ { return _M_call(__object, &__object, __args...); }
+
+ private:
+ _Functor __pmf;
+ };
+
+
+ template<typename _Res, typename _Class>
+ class _Mem_fn<_Res _Class::*>
+ {
+ // This bit of genius is due to Peter Dimov, improved slightly by
+ // Douglas Gregor.
+ template<typename _Tp>
+ _Res&
+ _M_call(_Tp& __object, _Class *) const
+ { return __object.*__pm; }
+
+ template<typename _Tp, typename _Up>
+ _Res&
+ _M_call(_Tp& __object, _Up * const *) const
+ { return (*__object).*__pm; }
+
+ template<typename _Tp, typename _Up>
+ const _Res&
+ _M_call(_Tp& __object, const _Up * const *) const
+ { return (*__object).*__pm; }
+
+ template<typename _Tp>
+ const _Res&
+ _M_call(_Tp& __object, const _Class *) const
+ { return __object.*__pm; }
+
+ template<typename _Tp>
+ const _Res&
+ _M_call(_Tp& __ptr, const volatile void*) const
+ { return (*__ptr).*__pm; }
+
+ template<typename _Tp> static _Tp& __get_ref();
+
+ template<typename _Tp>
+ static __sfinae_types::__one __check_const(_Tp&, _Class*);
+ template<typename _Tp, typename _Up>
+ static __sfinae_types::__one __check_const(_Tp&, _Up * const *);
+ template<typename _Tp, typename _Up>
+ static __sfinae_types::__two __check_const(_Tp&, const _Up * const *);
+ template<typename _Tp>
+ static __sfinae_types::__two __check_const(_Tp&, const _Class*);
+ template<typename _Tp>
+ static __sfinae_types::__two __check_const(_Tp&, const volatile void*);
+
+ public:
+ template<typename _Tp>
+ struct _Result_type
+ : _Mem_fn_const_or_non<_Res,
+ (sizeof(__sfinae_types::__two)
+ == sizeof(__check_const<_Tp>(__get_ref<_Tp>(), (_Tp*)0)))>
+ { };
+
+ template<typename _Signature>
+ struct result;
+
+ template<typename _CVMem, typename _Tp>
+ struct result<_CVMem(_Tp)>
+ : public _Result_type<_Tp> { };
+
+ template<typename _CVMem, typename _Tp>
+ struct result<_CVMem(_Tp&)>
+ : public _Result_type<_Tp> { };
+
+ explicit
+ _Mem_fn(_Res _Class::*__pm) : __pm(__pm) { }
+
+ // Handle objects
+ _Res&
+ operator()(_Class& __object) const
+ { return __object.*__pm; }
+
+ const _Res&
+ operator()(const _Class& __object) const
+ { return __object.*__pm; }
+
+ // Handle pointers
+ _Res&
+ operator()(_Class* __object) const
+ { return __object->*__pm; }
+
+ const _Res&
+ operator()(const _Class* __object) const
+ { return __object->*__pm; }
+
+ // Handle smart pointers and derived
+ template<typename _Tp>
+ typename _Result_type<_Tp>::type
+ operator()(_Tp& __unknown) const
+ { return _M_call(__unknown, &__unknown); }
+
+ private:
+ _Res _Class::*__pm;
+ };
+
+ /**
+ * @brief Returns a function object that forwards to the member
+ * pointer @a pm.
+ */
+ template<typename _Tp, typename _Class>
+ inline _Mem_fn<_Tp _Class::*>
+ mem_fn(_Tp _Class::* __pm)
+ {
+ return _Mem_fn<_Tp _Class::*>(__pm);
+ }
+
+ /**
+ * @brief Determines if the given type _Tp is a function object
+ * should be treated as a subexpression when evaluating calls to
+ * function objects returned by bind(). [TR1 3.6.1]
+ */
+ template<typename _Tp>
+ struct is_bind_expression
+ { static const bool value = false; };
+
+ template<typename _Tp>
+ const bool is_bind_expression<_Tp>::value;
+
+ /**
+ * @brief Determines if the given type _Tp is a placeholder in a
+ * bind() expression and, if so, which placeholder it is. [TR1 3.6.2]
+ */
+ template<typename _Tp>
+ struct is_placeholder
+ { static const int value = 0; };
+
+ template<typename _Tp>
+ const int is_placeholder<_Tp>::value;
+
+ /// The type of placeholder objects defined by libstdc++.
+ template<int _Num> struct _Placeholder { };
+
+ /** @namespace std::placeholders
+ * @brief ISO C++ 0x entities sub namespace for functional.
+ *
+ * Define a large number of placeholders. There is no way to
+ * simplify this with variadic templates, because we're introducing
+ * unique names for each.
+ */
+ namespace placeholders
+ {
+ namespace
+ {
+ _Placeholder<1> _1;
+ _Placeholder<2> _2;
+ _Placeholder<3> _3;
+ _Placeholder<4> _4;
+ _Placeholder<5> _5;
+ _Placeholder<6> _6;
+ _Placeholder<7> _7;
+ _Placeholder<8> _8;
+ _Placeholder<9> _9;
+ _Placeholder<10> _10;
+ _Placeholder<11> _11;
+ _Placeholder<12> _12;
+ _Placeholder<13> _13;
+ _Placeholder<14> _14;
+ _Placeholder<15> _15;
+ _Placeholder<16> _16;
+ _Placeholder<17> _17;
+ _Placeholder<18> _18;
+ _Placeholder<19> _19;
+ _Placeholder<20> _20;
+ _Placeholder<21> _21;
+ _Placeholder<22> _22;
+ _Placeholder<23> _23;
+ _Placeholder<24> _24;
+ _Placeholder<25> _25;
+ _Placeholder<26> _26;
+ _Placeholder<27> _27;
+ _Placeholder<28> _28;
+ _Placeholder<29> _29;
+ }
+ }
+
+ /**
+ * Partial specialization of is_placeholder that provides the placeholder
+ * number for the placeholder objects defined by libstdc++.
+ */
+ template<int _Num>
+ struct is_placeholder<_Placeholder<_Num> >
+ { static const int value = _Num; };
+
+ template<int _Num>
+ const int is_placeholder<_Placeholder<_Num> >::value;
+
+ /**
+ * Stores a tuple of indices. Used by bind() to extract the elements
+ * in a tuple.
+ */
+ template<int... _Indexes>
+ struct _Index_tuple { };
+
+ /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
+ template<std::size_t _Num, typename _Tuple = _Index_tuple<> >
+ struct _Build_index_tuple;
+
+ template<std::size_t _Num, int... _Indexes>
+ struct _Build_index_tuple<_Num, _Index_tuple<_Indexes...> >
+ : _Build_index_tuple<_Num - 1,
+ _Index_tuple<_Indexes..., sizeof...(_Indexes)> >
+ {
+ };
+
+ template<int... _Indexes>
+ struct _Build_index_tuple<0, _Index_tuple<_Indexes...> >
+ {
+ typedef _Index_tuple<_Indexes...> __type;
+ };
+
+ /**
+ * Used by _Safe_tuple_element to indicate that there is no tuple
+ * element at this position.
+ */
+ struct _No_tuple_element;
+
+ /**
+ * Implementation helper for _Safe_tuple_element. This primary
+ * template handles the case where it is safe to use @c
+ * tuple_element.
+ */
+ template<int __i, typename _Tuple, bool _IsSafe>
+ struct _Safe_tuple_element_impl
+ : tuple_element<__i, _Tuple> { };
+
+ /**
+ * Implementation helper for _Safe_tuple_element. This partial
+ * specialization handles the case where it is not safe to use @c
+ * tuple_element. We just return @c _No_tuple_element.
+ */
+ template<int __i, typename _Tuple>
+ struct _Safe_tuple_element_impl<__i, _Tuple, false>
+ {
+ typedef _No_tuple_element type;
+ };
+
+ /**
+ * Like tuple_element, but returns @c _No_tuple_element when
+ * tuple_element would return an error.
+ */
+ template<int __i, typename _Tuple>
+ struct _Safe_tuple_element
+ : _Safe_tuple_element_impl<__i, _Tuple,
+ (__i >= 0 && __i < tuple_size<_Tuple>::value)>
+ {
+ };
+
+ /**
+ * Maps an argument to bind() into an actual argument to the bound
+ * function object [TR1 3.6.3/5]. Only the first parameter should
+ * be specified: the rest are used to determine among the various
+ * implementations. Note that, although this class is a function
+ * object, it isn't entirely normal because it takes only two
+ * parameters regardless of the number of parameters passed to the
+ * bind expression. The first parameter is the bound argument and
+ * the second parameter is a tuple containing references to the
+ * rest of the arguments.
+ */
+ template<typename _Arg,
+ bool _IsBindExp = is_bind_expression<_Arg>::value,
+ bool _IsPlaceholder = (is_placeholder<_Arg>::value > 0)>
+ class _Mu;
+
+ /**
+ * If the argument is reference_wrapper<_Tp>, returns the
+ * underlying reference. [TR1 3.6.3/5 bullet 1]
+ */
+ template<typename _Tp>
+ class _Mu<reference_wrapper<_Tp>, false, false>
+ {
+ public:
+ typedef _Tp& result_type;
+
+ /* Note: This won't actually work for const volatile
+ * reference_wrappers, because reference_wrapper::get() is const
+ * but not volatile-qualified. This might be a defect in the TR.
+ */
+ template<typename _CVRef, typename _Tuple>
+ result_type
+ operator()(_CVRef& __arg, const _Tuple&) const volatile
+ { return __arg.get(); }
+ };
+
+ /**
+ * If the argument is a bind expression, we invoke the underlying
+ * function object with the same cv-qualifiers as we are given and
+ * pass along all of our arguments (unwrapped). [TR1 3.6.3/5 bullet 2]
+ */
+ template<typename _Arg>
+ class _Mu<_Arg, true, false>
+ {
+ public:
+ template<typename _Signature> class result;
+
+ // Determine the result type when we pass the arguments along. This
+ // involves passing along the cv-qualifiers placed on _Mu and
+ // unwrapping the argument bundle.
+ template<typename _CVMu, typename _CVArg, typename... _Args>
+ class result<_CVMu(_CVArg, tuple<_Args...>)>
+ : public result_of<_CVArg(_Args...)> { };
+
+ template<typename _CVArg, typename... _Args>
+ typename result_of<_CVArg(_Args...)>::type
+ operator()(_CVArg& __arg,
+ const tuple<_Args...>& __tuple) const volatile
+ {
+ // Construct an index tuple and forward to __call
+ typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
+ _Indexes;
+ return this->__call(__arg, __tuple, _Indexes());
+ }
+
+ private:
+ // Invokes the underlying function object __arg by unpacking all
+ // of the arguments in the tuple.
+ template<typename _CVArg, typename... _Args, int... _Indexes>
+ typename result_of<_CVArg(_Args...)>::type
+ __call(_CVArg& __arg, const tuple<_Args...>& __tuple,
+ const _Index_tuple<_Indexes...>&) const volatile
+ {
+ return __arg(tr1::get<_Indexes>(__tuple)...);
+ }
+ };
+
+ /**
+ * If the argument is a placeholder for the Nth argument, returns
+ * a reference to the Nth argument to the bind function object.
+ * [TR1 3.6.3/5 bullet 3]
+ */
+ template<typename _Arg>
+ class _Mu<_Arg, false, true>
+ {
+ public:
+ template<typename _Signature> class result;
+
+ template<typename _CVMu, typename _CVArg, typename _Tuple>
+ class result<_CVMu(_CVArg, _Tuple)>
+ {
+ // Add a reference, if it hasn't already been done for us.
+ // This allows us to be a little bit sloppy in constructing
+ // the tuple that we pass to result_of<...>.
+ typedef typename _Safe_tuple_element<(is_placeholder<_Arg>::value
+ - 1), _Tuple>::type
+ __base_type;
+
+ public:
+ typedef typename add_reference<__base_type>::type type;
+ };
+
+ template<typename _Tuple>
+ typename result<_Mu(_Arg, _Tuple)>::type
+ operator()(const volatile _Arg&, const _Tuple& __tuple) const volatile
+ {
+ return ::std::tr1::get<(is_placeholder<_Arg>::value - 1)>(__tuple);
+ }
+ };
+
+ /**
+ * If the argument is just a value, returns a reference to that
+ * value. The cv-qualifiers on the reference are the same as the
+ * cv-qualifiers on the _Mu object. [TR1 3.6.3/5 bullet 4]
+ */
+ template<typename _Arg>
+ class _Mu<_Arg, false, false>
+ {
+ public:
+ template<typename _Signature> struct result;
+
+ template<typename _CVMu, typename _CVArg, typename _Tuple>
+ struct result<_CVMu(_CVArg, _Tuple)>
+ {
+ typedef typename add_reference<_CVArg>::type type;
+ };
+
+ // Pick up the cv-qualifiers of the argument
+ template<typename _CVArg, typename _Tuple>
+ _CVArg&
+ operator()(_CVArg& __arg, const _Tuple&) const volatile
+ { return __arg; }
+ };
+
+ /**
+ * Maps member pointers into instances of _Mem_fn but leaves all
+ * other function objects untouched. Used by tr1::bind(). The
+ * primary template handles the non--member-pointer case.
+ */
+ template<typename _Tp>
+ struct _Maybe_wrap_member_pointer
+ {
+ typedef _Tp type;
+
+ static const _Tp&
+ __do_wrap(const _Tp& __x)
+ { return __x; }
+ };
+
+ /**
+ * Maps member pointers into instances of _Mem_fn but leaves all
+ * other function objects untouched. Used by tr1::bind(). This
+ * partial specialization handles the member pointer case.
+ */
+ template<typename _Tp, typename _Class>
+ struct _Maybe_wrap_member_pointer<_Tp _Class::*>
+ {
+ typedef _Mem_fn<_Tp _Class::*> type;
+
+ static type
+ __do_wrap(_Tp _Class::* __pm)
+ { return type(__pm); }
+ };
+
+ /// Type of the function object returned from bind().
+ template<typename _Signature>
+ struct _Bind;
+
+ template<typename _Functor, typename... _Bound_args>
+ class _Bind<_Functor(_Bound_args...)>
+ : public _Weak_result_type<_Functor>
+ {
+ typedef _Bind __self_type;
+ typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type
+ _Bound_indexes;
+
+ _Functor _M_f;
+ tuple<_Bound_args...> _M_bound_args;
+
+ // Call unqualified
+ template<typename... _Args, int... _Indexes>
+ typename result_of<
+ _Functor(typename result_of<_Mu<_Bound_args>
+ (_Bound_args, tuple<_Args...>)>::type...)
+ >::type
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>)
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (tr1::get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ // Call as const
+ template<typename... _Args, int... _Indexes>
+ typename result_of<
+ const _Functor(typename result_of<_Mu<_Bound_args>
+ (const _Bound_args, tuple<_Args...>)
+ >::type...)>::type
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) const
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (tr1::get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ // Call as volatile
+ template<typename... _Args, int... _Indexes>
+ typename result_of<
+ volatile _Functor(typename result_of<_Mu<_Bound_args>
+ (volatile _Bound_args, tuple<_Args...>)
+ >::type...)>::type
+ __call(const tuple<_Args...>& __args,
+ _Index_tuple<_Indexes...>) volatile
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (tr1::get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ // Call as const volatile
+ template<typename... _Args, int... _Indexes>
+ typename result_of<
+ const volatile _Functor(typename result_of<_Mu<_Bound_args>
+ (const volatile _Bound_args,
+ tuple<_Args...>)
+ >::type...)>::type
+ __call(const tuple<_Args...>& __args,
+ _Index_tuple<_Indexes...>) const volatile
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (tr1::get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ public:
+ explicit _Bind(_Functor __f, _Bound_args... __bound_args)
+ : _M_f(__f), _M_bound_args(__bound_args...) { }
+
+ // Call unqualified
+ template<typename... _Args>
+ typename result_of<
+ _Functor(typename result_of<_Mu<_Bound_args>
+ (_Bound_args, tuple<_Args...>)>::type...)
+ >::type
+ operator()(_Args&... __args)
+ {
+ return this->__call(tr1::tie(__args...), _Bound_indexes());
+ }
+
+ // Call as const
+ template<typename... _Args>
+ typename result_of<
+ const _Functor(typename result_of<_Mu<_Bound_args>
+ (const _Bound_args, tuple<_Args...>)>::type...)
+ >::type
+ operator()(_Args&... __args) const
+ {
+ return this->__call(tr1::tie(__args...), _Bound_indexes());
+ }
+
+
+ // Call as volatile
+ template<typename... _Args>
+ typename result_of<
+ volatile _Functor(typename result_of<_Mu<_Bound_args>
+ (volatile _Bound_args, tuple<_Args...>)>::type...)
+ >::type
+ operator()(_Args&... __args) volatile
+ {
+ return this->__call(tr1::tie(__args...), _Bound_indexes());
+ }
+
+
+ // Call as const volatile
+ template<typename... _Args>
+ typename result_of<
+ const volatile _Functor(typename result_of<_Mu<_Bound_args>
+ (const volatile _Bound_args,
+ tuple<_Args...>)>::type...)
+ >::type
+ operator()(_Args&... __args) const volatile
+ {
+ return this->__call(tr1::tie(__args...), _Bound_indexes());
+ }
+ };
+
+ /// Type of the function object returned from bind<R>().
+ template<typename _Result, typename _Signature>
+ struct _Bind_result;
+
+ template<typename _Result, typename _Functor, typename... _Bound_args>
+ class _Bind_result<_Result, _Functor(_Bound_args...)>
+ {
+ typedef _Bind_result __self_type;
+ typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type
+ _Bound_indexes;
+
+ _Functor _M_f;
+ tuple<_Bound_args...> _M_bound_args;
+
+ // Call unqualified
+ template<typename... _Args, int... _Indexes>
+ _Result
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>)
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (tr1::get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ // Call as const
+ template<typename... _Args, int... _Indexes>
+ _Result
+ __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) const
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (tr1::get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ // Call as volatile
+ template<typename... _Args, int... _Indexes>
+ _Result
+ __call(const tuple<_Args...>& __args,
+ _Index_tuple<_Indexes...>) volatile
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (tr1::get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ // Call as const volatile
+ template<typename... _Args, int... _Indexes>
+ _Result
+ __call(const tuple<_Args...>& __args,
+ _Index_tuple<_Indexes...>) const volatile
+ {
+ return _M_f(_Mu<_Bound_args>()
+ (tr1::get<_Indexes>(_M_bound_args), __args)...);
+ }
+
+ public:
+ typedef _Result result_type;
+
+ explicit
+ _Bind_result(_Functor __f, _Bound_args... __bound_args)
+ : _M_f(__f), _M_bound_args(__bound_args...) { }
+
+ // Call unqualified
+ template<typename... _Args>
+ result_type
+ operator()(_Args&... __args)
+ {
+ return this->__call(tr1::tie(__args...), _Bound_indexes());
+ }
+
+ // Call as const
+ template<typename... _Args>
+ result_type
+ operator()(_Args&... __args) const
+ {
+ return this->__call(tr1::tie(__args...), _Bound_indexes());
+ }
+
+ // Call as volatile
+ template<typename... _Args>
+ result_type
+ operator()(_Args&... __args) volatile
+ {
+ return this->__call(tr1::tie(__args...), _Bound_indexes());
+ }
+
+ // Call as const volatile
+ template<typename... _Args>
+ result_type
+ operator()(_Args&... __args) const volatile
+ {
+ return this->__call(tr1::tie(__args...), _Bound_indexes());
+ }
+ };
+
+ /// Class template _Bind is always a bind expression.
+ template<typename _Signature>
+ struct is_bind_expression<_Bind<_Signature> >
+ { static const bool value = true; };
+
+ template<typename _Signature>
+ const bool is_bind_expression<_Bind<_Signature> >::value;
+
+ /// Class template _Bind_result is always a bind expression.
+ template<typename _Result, typename _Signature>
+ struct is_bind_expression<_Bind_result<_Result, _Signature> >
+ { static const bool value = true; };
+
+ template<typename _Result, typename _Signature>
+ const bool is_bind_expression<_Bind_result<_Result, _Signature> >::value;
+
+ /// bind
+ template<typename _Functor, typename... _ArgTypes>
+ inline
+ _Bind<typename _Maybe_wrap_member_pointer<_Functor>::type(_ArgTypes...)>
+ bind(_Functor __f, _ArgTypes... __args)
+ {
+ typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
+ typedef typename __maybe_type::type __functor_type;
+ typedef _Bind<__functor_type(_ArgTypes...)> __result_type;
+ return __result_type(__maybe_type::__do_wrap(__f), __args...);
+ }
+
+ template<typename _Result, typename _Functor, typename... _ArgTypes>
+ inline
+ _Bind_result<_Result,
+ typename _Maybe_wrap_member_pointer<_Functor>::type
+ (_ArgTypes...)>
+ bind(_Functor __f, _ArgTypes... __args)
+ {
+ typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
+ typedef typename __maybe_type::type __functor_type;
+ typedef _Bind_result<_Result, __functor_type(_ArgTypes...)>
+ __result_type;
+ return __result_type(__maybe_type::__do_wrap(__f), __args...);
+ }
+
+ /**
+ * @brief Exception class thrown when class template function's
+ * operator() is called with an empty target.
+ * @ingroup exceptions
+ */
+ class bad_function_call : public std::exception { };
+
+ /**
+ * The integral constant expression 0 can be converted into a
+ * pointer to this type. It is used by the function template to
+ * accept NULL pointers.
+ */
+ struct _M_clear_type;
+
+ /**
+ * Trait identifying "location-invariant" types, meaning that the
+ * address of the object (or any of its members) will not escape.
+ * Also implies a trivial copy constructor and assignment operator.
+ */
+ template<typename _Tp>
+ struct __is_location_invariant
+ : integral_constant<bool,
+ (is_pointer<_Tp>::value
+ || is_member_pointer<_Tp>::value)>
+ {
+ };
+
+ class _Undefined_class;
+
+ union _Nocopy_types
+ {
+ void* _M_object;
+ const void* _M_const_object;
+ void (*_M_function_pointer)();
+ void (_Undefined_class::*_M_member_pointer)();
+ };
+
+ union _Any_data
+ {
+ void* _M_access() { return &_M_pod_data[0]; }
+ const void* _M_access() const { return &_M_pod_data[0]; }
+
+ template<typename _Tp>
+ _Tp&
+ _M_access()
+ { return *static_cast<_Tp*>(_M_access()); }
+
+ template<typename _Tp>
+ const _Tp&
+ _M_access() const
+ { return *static_cast<const _Tp*>(_M_access()); }
+
+ _Nocopy_types _M_unused;
+ char _M_pod_data[sizeof(_Nocopy_types)];
+ };
+
+ enum _Manager_operation
+ {
+ __get_type_info,
+ __get_functor_ptr,
+ __clone_functor,
+ __destroy_functor
+ };
+
+ // Simple type wrapper that helps avoid annoying const problems
+ // when casting between void pointers and pointers-to-pointers.
+ template<typename _Tp>
+ struct _Simple_type_wrapper
+ {
+ _Simple_type_wrapper(_Tp __value) : __value(__value) { }
+
+ _Tp __value;
+ };
+
+ template<typename _Tp>
+ struct __is_location_invariant<_Simple_type_wrapper<_Tp> >
+ : __is_location_invariant<_Tp>
+ {
+ };
+
+ // Converts a reference to a function object into a callable
+ // function object.
+ template<typename _Functor>
+ inline _Functor&
+ __callable_functor(_Functor& __f)
+ { return __f; }
+
+ template<typename _Member, typename _Class>
+ inline _Mem_fn<_Member _Class::*>
+ __callable_functor(_Member _Class::* &__p)
+ { return mem_fn(__p); }
+
+ template<typename _Member, typename _Class>
+ inline _Mem_fn<_Member _Class::*>
+ __callable_functor(_Member _Class::* const &__p)
+ { return mem_fn(__p); }
+
+ template<typename _Signature>
+ class function;
+
+ /// Base class of all polymorphic function object wrappers.
+ class _Function_base
+ {
+ public:
+ static const std::size_t _M_max_size = sizeof(_Nocopy_types);
+ static const std::size_t _M_max_align = __alignof__(_Nocopy_types);
+
+ template<typename _Functor>
+ class _Base_manager
+ {
+ protected:
+ static const bool __stored_locally =
+ (__is_location_invariant<_Functor>::value
+ && sizeof(_Functor) <= _M_max_size
+ && __alignof__(_Functor) <= _M_max_align
+ && (_M_max_align % __alignof__(_Functor) == 0));
+
+ typedef integral_constant<bool, __stored_locally> _Local_storage;
+
+ // Retrieve a pointer to the function object
+ static _Functor*
+ _M_get_pointer(const _Any_data& __source)
+ {
+ const _Functor* __ptr =
+ __stored_locally? &__source._M_access<_Functor>()
+ /* have stored a pointer */ : __source._M_access<_Functor*>();
+ return const_cast<_Functor*>(__ptr);
+ }
+
+ // Clone a location-invariant function object that fits within
+ // an _Any_data structure.
+ static void
+ _M_clone(_Any_data& __dest, const _Any_data& __source, true_type)
+ {
+ new (__dest._M_access()) _Functor(__source._M_access<_Functor>());
+ }
+
+ // Clone a function object that is not location-invariant or
+ // that cannot fit into an _Any_data structure.
+ static void
+ _M_clone(_Any_data& __dest, const _Any_data& __source, false_type)
+ {
+ __dest._M_access<_Functor*>() =
+ new _Functor(*__source._M_access<_Functor*>());
+ }
+
+ // Destroying a location-invariant object may still require
+ // destruction.
+ static void
+ _M_destroy(_Any_data& __victim, true_type)
+ {
+ __victim._M_access<_Functor>().~_Functor();
+ }
+
+ // Destroying an object located on the heap.
+ static void
+ _M_destroy(_Any_data& __victim, false_type)
+ {
+ delete __victim._M_access<_Functor*>();
+ }
+
+ public:
+ static bool
+ _M_manager(_Any_data& __dest, const _Any_data& __source,
+ _Manager_operation __op)
+ {
+ switch (__op)
+ {
+#ifdef __GXX_RTTI
+ case __get_type_info:
+ __dest._M_access<const type_info*>() = &typeid(_Functor);
+ break;
+#endif
+ case __get_functor_ptr:
+ __dest._M_access<_Functor*>() = _M_get_pointer(__source);
+ break;
+
+ case __clone_functor:
+ _M_clone(__dest, __source, _Local_storage());
+ break;
+
+ case __destroy_functor:
+ _M_destroy(__dest, _Local_storage());
+ break;
+ }
+ return false;
+ }
+
+ static void
+ _M_init_functor(_Any_data& __functor, const _Functor& __f)
+ { _M_init_functor(__functor, __f, _Local_storage()); }
+
+ template<typename _Signature>
+ static bool
+ _M_not_empty_function(const function<_Signature>& __f)
+ { return static_cast<bool>(__f); }
+
+ template<typename _Tp>
+ static bool
+ _M_not_empty_function(const _Tp*& __fp)
+ { return __fp; }
+
+ template<typename _Class, typename _Tp>
+ static bool
+ _M_not_empty_function(_Tp _Class::* const& __mp)
+ { return __mp; }
+
+ template<typename _Tp>
+ static bool
+ _M_not_empty_function(const _Tp&)
+ { return true; }
+
+ private:
+ static void
+ _M_init_functor(_Any_data& __functor, const _Functor& __f, true_type)
+ { new (__functor._M_access()) _Functor(__f); }
+
+ static void
+ _M_init_functor(_Any_data& __functor, const _Functor& __f, false_type)
+ { __functor._M_access<_Functor*>() = new _Functor(__f); }
+ };
+
+ template<typename _Functor>
+ class _Ref_manager : public _Base_manager<_Functor*>
+ {
+ typedef _Function_base::_Base_manager<_Functor*> _Base;
+
+ public:
+ static bool
+ _M_manager(_Any_data& __dest, const _Any_data& __source,
+ _Manager_operation __op)
+ {
+ switch (__op)
+ {
+#ifdef __GXX_RTTI
+ case __get_type_info:
+ __dest._M_access<const type_info*>() = &typeid(_Functor);
+ break;
+#endif
+ case __get_functor_ptr:
+ __dest._M_access<_Functor*>() = *_Base::_M_get_pointer(__source);
+ return is_const<_Functor>::value;
+ break;
+
+ default:
+ _Base::_M_manager(__dest, __source, __op);
+ }
+ return false;
+ }
+
+ static void
+ _M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f)
+ {
+ // TBD: Use address_of function instead.
+ _Base::_M_init_functor(__functor, &__f.get());
+ }
+ };
+
+ _Function_base() : _M_manager(0) { }
+
+ ~_Function_base()
+ {
+ if (_M_manager)
+ _M_manager(_M_functor, _M_functor, __destroy_functor);
+ }
+
+
+ bool _M_empty() const { return !_M_manager; }
+
+ typedef bool (*_Manager_type)(_Any_data&, const _Any_data&,
+ _Manager_operation);
+
+ _Any_data _M_functor;
+ _Manager_type _M_manager;
+ };
+
+ template<typename _Signature, typename _Functor>
+ class _Function_handler;
+
+ template<typename _Res, typename _Functor, typename... _ArgTypes>
+ class _Function_handler<_Res(_ArgTypes...), _Functor>
+ : public _Function_base::_Base_manager<_Functor>
+ {
+ typedef _Function_base::_Base_manager<_Functor> _Base;
+
+ public:
+ static _Res
+ _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
+ {
+ return (*_Base::_M_get_pointer(__functor))(__args...);
+ }
+ };
+
+ template<typename _Functor, typename... _ArgTypes>
+ class _Function_handler<void(_ArgTypes...), _Functor>
+ : public _Function_base::_Base_manager<_Functor>
+ {
+ typedef _Function_base::_Base_manager<_Functor> _Base;
+
+ public:
+ static void
+ _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
+ {
+ (*_Base::_M_get_pointer(__functor))(__args...);
+ }
+ };
+
+ template<typename _Res, typename _Functor, typename... _ArgTypes>
+ class _Function_handler<_Res(_ArgTypes...), reference_wrapper<_Functor> >
+ : public _Function_base::_Ref_manager<_Functor>
+ {
+ typedef _Function_base::_Ref_manager<_Functor> _Base;
+
+ public:
+ static _Res
+ _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
+ {
+ return
+ __callable_functor(**_Base::_M_get_pointer(__functor))(__args...);
+ }
+ };
+
+ template<typename _Functor, typename... _ArgTypes>
+ class _Function_handler<void(_ArgTypes...), reference_wrapper<_Functor> >
+ : public _Function_base::_Ref_manager<_Functor>
+ {
+ typedef _Function_base::_Ref_manager<_Functor> _Base;
+
+ public:
+ static void
+ _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
+ {
+ __callable_functor(**_Base::_M_get_pointer(__functor))(__args...);
+ }
+ };
+
+ template<typename _Class, typename _Member, typename _Res,
+ typename... _ArgTypes>
+ class _Function_handler<_Res(_ArgTypes...), _Member _Class::*>
+ : public _Function_handler<void(_ArgTypes...), _Member _Class::*>
+ {
+ typedef _Function_handler<void(_ArgTypes...), _Member _Class::*>
+ _Base;
+
+ public:
+ static _Res
+ _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
+ {
+ return tr1::
+ mem_fn(_Base::_M_get_pointer(__functor)->__value)(__args...);
+ }
+ };
+
+ template<typename _Class, typename _Member, typename... _ArgTypes>
+ class _Function_handler<void(_ArgTypes...), _Member _Class::*>
+ : public _Function_base::_Base_manager<
+ _Simple_type_wrapper< _Member _Class::* > >
+ {
+ typedef _Member _Class::* _Functor;
+ typedef _Simple_type_wrapper<_Functor> _Wrapper;
+ typedef _Function_base::_Base_manager<_Wrapper> _Base;
+
+ public:
+ static bool
+ _M_manager(_Any_data& __dest, const _Any_data& __source,
+ _Manager_operation __op)
+ {
+ switch (__op)
+ {
+#ifdef __GXX_RTTI
+ case __get_type_info:
+ __dest._M_access<const type_info*>() = &typeid(_Functor);
+ break;
+#endif
+ case __get_functor_ptr:
+ __dest._M_access<_Functor*>() =
+ &_Base::_M_get_pointer(__source)->__value;
+ break;
+
+ default:
+ _Base::_M_manager(__dest, __source, __op);
+ }
+ return false;
+ }
+
+ static void
+ _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
+ {
+ tr1::mem_fn(_Base::_M_get_pointer(__functor)->__value)(__args...);
+ }
+ };
+
+ /// class function
+ template<typename _Res, typename... _ArgTypes>
+ class function<_Res(_ArgTypes...)>
+ : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,
+ private _Function_base
+ {
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
+ /// This class is used to implement the safe_bool idiom.
+ struct _Hidden_type
+ {
+ _Hidden_type* _M_bool;
+ };
+
+ /// This typedef is used to implement the safe_bool idiom.
+ typedef _Hidden_type* _Hidden_type::* _Safe_bool;
+#endif
+
+ typedef _Res _Signature_type(_ArgTypes...);
+
+ struct _Useless { };
+
+ public:
+ typedef _Res result_type;
+
+ // [3.7.2.1] construct/copy/destroy
+
+ /**
+ * @brief Default construct creates an empty function call wrapper.
+ * @post @c !(bool)*this
+ */
+ function() : _Function_base() { }
+
+ /**
+ * @brief Default construct creates an empty function call wrapper.
+ * @post @c !(bool)*this
+ */
+ function(_M_clear_type*) : _Function_base() { }
+
+ /**
+ * @brief %Function copy constructor.
+ * @param x A %function object with identical call signature.
+ * @post @c (bool)*this == (bool)x
+ *
+ * The newly-created %function contains a copy of the target of @a
+ * x (if it has one).
+ */
+ function(const function& __x);
+
+ /**
+ * @brief Builds a %function that targets a copy of the incoming
+ * function object.
+ * @param f A %function object that is callable with parameters of
+ * type @c T1, @c T2, ..., @c TN and returns a value convertible
+ * to @c Res.
+ *
+ * The newly-created %function object will target a copy of @a
+ * f. If @a f is @c reference_wrapper<F>, then this function
+ * object will contain a reference to the function object @c
+ * f.get(). If @a f is a NULL function pointer or NULL
+ * pointer-to-member, the newly-created object will be empty.
+ *
+ * If @a f is a non-NULL function pointer or an object of type @c
+ * reference_wrapper<F>, this function will not throw.
+ */
+ template<typename _Functor>
+ function(_Functor __f,
+ typename __gnu_cxx::__enable_if<
+ !is_integral<_Functor>::value, _Useless>::__type
+ = _Useless());
+
+ /**
+ * @brief %Function assignment operator.
+ * @param x A %function with identical call signature.
+ * @post @c (bool)*this == (bool)x
+ * @returns @c *this
+ *
+ * The target of @a x is copied to @c *this. If @a x has no
+ * target, then @c *this will be empty.
+ *
+ * If @a x targets a function pointer or a reference to a function
+ * object, then this operation will not throw an %exception.
+ */
+ function&
+ operator=(const function& __x)
+ {
+ function(__x).swap(*this);
+ return *this;
+ }
+
+ /**
+ * @brief %Function assignment to zero.
+ * @post @c !(bool)*this
+ * @returns @c *this
+ *
+ * The target of @c *this is deallocated, leaving it empty.
+ */
+ function&
+ operator=(_M_clear_type*)
+ {
+ if (_M_manager)
+ {
+ _M_manager(_M_functor, _M_functor, __destroy_functor);
+ _M_manager = 0;
+ _M_invoker = 0;
+ }
+ return *this;
+ }
+
+ /**
+ * @brief %Function assignment to a new target.
+ * @param f A %function object that is callable with parameters of
+ * type @c T1, @c T2, ..., @c TN and returns a value convertible
+ * to @c Res.
+ * @return @c *this
+ *
+ * This %function object wrapper will target a copy of @a
+ * f. If @a f is @c reference_wrapper<F>, then this function
+ * object will contain a reference to the function object @c
+ * f.get(). If @a f is a NULL function pointer or NULL
+ * pointer-to-member, @c this object will be empty.
+ *
+ * If @a f is a non-NULL function pointer or an object of type @c
+ * reference_wrapper<F>, this function will not throw.
+ */
+ template<typename _Functor>
+ typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value,
+ function&>::__type
+ operator=(_Functor __f)
+ {
+ function(__f).swap(*this);
+ return *this;
+ }
+
+ // [3.7.2.2] function modifiers
+
+ /**
+ * @brief Swap the targets of two %function objects.
+ * @param f A %function with identical call signature.
+ *
+ * Swap the targets of @c this function object and @a f. This
+ * function will not throw an %exception.
+ */
+ void swap(function& __x)
+ {
+ _Any_data __old_functor = _M_functor;
+ _M_functor = __x._M_functor;
+ __x._M_functor = __old_functor;
+ _Manager_type __old_manager = _M_manager;
+ _M_manager = __x._M_manager;
+ __x._M_manager = __old_manager;
+ _Invoker_type __old_invoker = _M_invoker;
+ _M_invoker = __x._M_invoker;
+ __x._M_invoker = __old_invoker;
+ }
+
+ // [3.7.2.3] function capacity
+
+ /**
+ * @brief Determine if the %function wrapper has a target.
+ *
+ * @return @c true when this %function object contains a target,
+ * or @c false when it is empty.
+ *
+ * This function will not throw an %exception.
+ */
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ explicit operator bool() const
+ { return !_M_empty(); }
#else
-# define _GLIBCXX_INCLUDE_AS_TR1
-# define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 {
-# define _GLIBCXX_END_NAMESPACE_TR1 }
-# define _GLIBCXX_TR1 tr1::
-# include <tr1_impl/functional>
-# undef _GLIBCXX_TR1
-# undef _GLIBCXX_END_NAMESPACE_TR1
-# undef _GLIBCXX_BEGIN_NAMESPACE_TR1
-# undef _GLIBCXX_INCLUDE_AS_TR1
+ operator _Safe_bool() const
+ {
+ if (_M_empty())
+ return 0;
+ else
+ return &_Hidden_type::_M_bool;
+ }
#endif
+ // [3.7.2.4] function invocation
+
+ /**
+ * @brief Invokes the function targeted by @c *this.
+ * @returns the result of the target.
+ * @throws bad_function_call when @c !(bool)*this
+ *
+ * The function call operator invokes the target function object
+ * stored by @c this.
+ */
+ _Res operator()(_ArgTypes... __args) const;
+
+#ifdef __GXX_RTTI
+ // [3.7.2.5] function target access
+ /**
+ * @brief Determine the type of the target of this function object
+ * wrapper.
+ *
+ * @returns the type identifier of the target function object, or
+ * @c typeid(void) if @c !(bool)*this.
+ *
+ * This function will not throw an %exception.
+ */
+ const type_info& target_type() const;
+
+ /**
+ * @brief Access the stored target function object.
+ *
+ * @return Returns a pointer to the stored target function object,
+ * if @c typeid(Functor).equals(target_type()); otherwise, a NULL
+ * pointer.
+ *
+ * This function will not throw an %exception.
+ */
+ template<typename _Functor> _Functor* target();
+
+ /// @overload
+ template<typename _Functor> const _Functor* target() const;
+#endif
+
+ private:
+ // [3.7.2.6] undefined operators
+ template<typename _Function>
+ void operator==(const function<_Function>&) const;
+ template<typename _Function>
+ void operator!=(const function<_Function>&) const;
+
+ typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...);
+ _Invoker_type _M_invoker;
+ };
+
+ template<typename _Res, typename... _ArgTypes>
+ function<_Res(_ArgTypes...)>::
+ function(const function& __x)
+ : _Function_base()
+ {
+ if (static_cast<bool>(__x))
+ {
+ _M_invoker = __x._M_invoker;
+ _M_manager = __x._M_manager;
+ __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
+ }
+ }
+
+ template<typename _Res, typename... _ArgTypes>
+ template<typename _Functor>
+ function<_Res(_ArgTypes...)>::
+ function(_Functor __f,
+ typename __gnu_cxx::__enable_if<
+ !is_integral<_Functor>::value, _Useless>::__type)
+ : _Function_base()
+ {
+ typedef _Function_handler<_Signature_type, _Functor> _My_handler;
+
+ if (_My_handler::_M_not_empty_function(__f))
+ {
+ _M_invoker = &_My_handler::_M_invoke;
+ _M_manager = &_My_handler::_M_manager;
+ _My_handler::_M_init_functor(_M_functor, __f);
+ }
+ }
+
+ template<typename _Res, typename... _ArgTypes>
+ _Res
+ function<_Res(_ArgTypes...)>::
+ operator()(_ArgTypes... __args) const
+ {
+ if (_M_empty())
+ {
+#if __EXCEPTIONS
+ throw bad_function_call();
+#else
+ __builtin_abort();
+#endif
+ }
+ return _M_invoker(_M_functor, __args...);
+ }
+
+#ifdef __GXX_RTTI
+ template<typename _Res, typename... _ArgTypes>
+ const type_info&
+ function<_Res(_ArgTypes...)>::
+ target_type() const
+ {
+ if (_M_manager)
+ {
+ _Any_data __typeinfo_result;
+ _M_manager(__typeinfo_result, _M_functor, __get_type_info);
+ return *__typeinfo_result._M_access<const type_info*>();
+ }
+ else
+ return typeid(void);
+ }
+
+ template<typename _Res, typename... _ArgTypes>
+ template<typename _Functor>
+ _Functor*
+ function<_Res(_ArgTypes...)>::
+ target()
+ {
+ if (typeid(_Functor) == target_type() && _M_manager)
+ {
+ _Any_data __ptr;
+ if (_M_manager(__ptr, _M_functor, __get_functor_ptr)
+ && !is_const<_Functor>::value)
+ return 0;
+ else
+ return __ptr._M_access<_Functor*>();
+ }
+ else
+ return 0;
+ }
+
+ template<typename _Res, typename... _ArgTypes>
+ template<typename _Functor>
+ const _Functor*
+ function<_Res(_ArgTypes...)>::
+ target() const
+ {
+ if (typeid(_Functor) == target_type() && _M_manager)
+ {
+ _Any_data __ptr;
+ _M_manager(__ptr, _M_functor, __get_functor_ptr);
+ return __ptr._M_access<const _Functor*>();
+ }
+ else
+ return 0;
+ }
+#endif
+
+ // [3.7.2.7] null pointer comparisons
+
+ /**
+ * @brief Compares a polymorphic function object wrapper against 0
+ * (the NULL pointer).
+ * @returns @c true if the wrapper has no target, @c false otherwise
+ *
+ * This function will not throw an %exception.
+ */
+ template<typename _Signature>
+ inline bool
+ operator==(const function<_Signature>& __f, _M_clear_type*)
+ { return !static_cast<bool>(__f); }
+
+ /// @overload
+ template<typename _Signature>
+ inline bool
+ operator==(_M_clear_type*, const function<_Signature>& __f)
+ { return !static_cast<bool>(__f); }
+
+ /**
+ * @brief Compares a polymorphic function object wrapper against 0
+ * (the NULL pointer).
+ * @returns @c false if the wrapper has no target, @c true otherwise
+ *
+ * This function will not throw an %exception.
+ */
+ template<typename _Signature>
+ inline bool
+ operator!=(const function<_Signature>& __f, _M_clear_type*)
+ { return static_cast<bool>(__f); }
+
+ /// @overload
+ template<typename _Signature>
+ inline bool
+ operator!=(_M_clear_type*, const function<_Signature>& __f)
+ { return static_cast<bool>(__f); }
+
+ // [3.7.2.8] specialized algorithms
+
+ /**
+ * @brief Swap the targets of two polymorphic function object wrappers.
+ *
+ * This function will not throw an %exception.
+ */
+ template<typename _Signature>
+ inline void
+ swap(function<_Signature>& __x, function<_Signature>& __y)
+ { __x.swap(__y); }
+}
+}
+
#endif // _GLIBCXX_TR1_FUNCTIONAL
diff --git a/libstdc++-v3/include/tr1_impl/functional b/libstdc++-v3/include/tr1_impl/functional
deleted file mode 100644
index 9911d46d678..00000000000
--- a/libstdc++-v3/include/tr1_impl/functional
+++ /dev/null
@@ -1,2137 +0,0 @@
-// TR1 functional header -*- C++ -*-
-
-// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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.
-
-// This library 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.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-// <http://www.gnu.org/licenses/>.
-
-/** @file tr1_impl/functional
- * This is an internal header file, included by other library headers.
- * You should not attempt to use it directly.
- */
-
-namespace std
-{
-_GLIBCXX_BEGIN_NAMESPACE_TR1
-
- template<typename _MemberPointer>
- class _Mem_fn;
-
- /**
- * Actual implementation of _Has_result_type, which uses SFINAE to
- * determine if the type _Tp has a publicly-accessible member type
- * result_type.
- */
- template<typename _Tp>
- class _Has_result_type_helper : __sfinae_types
- {
- template<typename _Up>
- struct _Wrap_type
- { };
-
- template<typename _Up>
- static __one __test(_Wrap_type<typename _Up::result_type>*);
-
- template<typename _Up>
- static __two __test(...);
-
- public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
- };
-
- template<typename _Tp>
- struct _Has_result_type
- : integral_constant<bool,
- _Has_result_type_helper<typename remove_cv<_Tp>::type>::value>
- { };
-
- /**
- *
- */
- /// If we have found a result_type, extract it.
- template<bool _Has_result_type, typename _Functor>
- struct _Maybe_get_result_type
- { };
-
- template<typename _Functor>
- struct _Maybe_get_result_type<true, _Functor>
- {
- typedef typename _Functor::result_type result_type;
- };
-
- /**
- * Base class for any function object that has a weak result type, as
- * defined in 3.3/3 of TR1.
- */
- template<typename _Functor>
- struct _Weak_result_type_impl
- : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor>
- {
- };
-
- /// Retrieve the result type for a function type.
- template<typename _Res, typename... _ArgTypes>
- struct _Weak_result_type_impl<_Res(_ArgTypes...)>
- {
- typedef _Res result_type;
- };
-
- /// Retrieve the result type for a function reference.
- template<typename _Res, typename... _ArgTypes>
- struct _Weak_result_type_impl<_Res(&)(_ArgTypes...)>
- {
- typedef _Res result_type;
- };
-
- /// Retrieve the result type for a function pointer.
- template<typename _Res, typename... _ArgTypes>
- struct _Weak_result_type_impl<_Res(*)(_ArgTypes...)>
- {
- typedef _Res result_type;
- };
-
- /// Retrieve result type for a member function pointer.
- template<typename _Res, typename _Class, typename... _ArgTypes>
- struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)>
- {
- typedef _Res result_type;
- };
-
- /// Retrieve result type for a const member function pointer.
- template<typename _Res, typename _Class, typename... _ArgTypes>
- struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) const>
- {
- typedef _Res result_type;
- };
-
- /// Retrieve result type for a volatile member function pointer.
- template<typename _Res, typename _Class, typename... _ArgTypes>
- struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) volatile>
- {
- typedef _Res result_type;
- };
-
- /// Retrieve result type for a const volatile member function pointer.
- template<typename _Res, typename _Class, typename... _ArgTypes>
- struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)const volatile>
- {
- typedef _Res result_type;
- };
-
- /**
- * Strip top-level cv-qualifiers from the function object and let
- * _Weak_result_type_impl perform the real work.
- */
- template<typename _Functor>
- struct _Weak_result_type
- : _Weak_result_type_impl<typename remove_cv<_Functor>::type>
- {
- };
-
- template<typename _Signature>
- class result_of;
-
- /**
- * Actual implementation of result_of. When _Has_result_type is
- * true, gets its result from _Weak_result_type. Otherwise, uses
- * the function object's member template result to extract the
- * result type.
- */
- template<bool _Has_result_type, typename _Signature>
- struct _Result_of_impl;
-
- // Handle member data pointers using _Mem_fn's logic
- template<typename _Res, typename _Class, typename _T1>
- struct _Result_of_impl<false, _Res _Class::*(_T1)>
- {
- typedef typename _Mem_fn<_Res _Class::*>
- ::template _Result_type<_T1>::type type;
- };
-
- /**
- * Determine whether we can determine a result type from @c Functor
- * alone.
- */
- template<typename _Functor, typename... _ArgTypes>
- class result_of<_Functor(_ArgTypes...)>
- : public _Result_of_impl<
- _Has_result_type<_Weak_result_type<_Functor> >::value,
- _Functor(_ArgTypes...)>
- {
- };
-
- /// We already know the result type for @c Functor; use it.
- template<typename _Functor, typename... _ArgTypes>
- struct _Result_of_impl<true, _Functor(_ArgTypes...)>
- {
- typedef typename _Weak_result_type<_Functor>::result_type type;
- };
-
- /**
- * We need to compute the result type for this invocation the hard
- * way.
- */
- template<typename _Functor, typename... _ArgTypes>
- struct _Result_of_impl<false, _Functor(_ArgTypes...)>
- {
- typedef typename _Functor
- ::template result<_Functor(_ArgTypes...)>::type type;
- };
-
- /**
- * It is unsafe to access ::result when there are zero arguments, so we
- * return @c void instead.
- */
- template<typename _Functor>
- struct _Result_of_impl<false, _Functor()>
- {
- typedef void type;
- };
-
- /// Determines if the type _Tp derives from unary_function.
- template<typename _Tp>
- struct _Derives_from_unary_function : __sfinae_types
- {
- private:
- template<typename _T1, typename _Res>
- static __one __test(const volatile unary_function<_T1, _Res>*);
-
- // It's tempting to change "..." to const volatile void*, but
- // that fails when _Tp is a function type.
- static __two __test(...);
-
- public:
- static const bool value = sizeof(__test((_Tp*)0)) == 1;
- };
-
- /// Determines if the type _Tp derives from binary_function.
- template<typename _Tp>
- struct _Derives_from_binary_function : __sfinae_types
- {
- private:
- template<typename _T1, typename _T2, typename _Res>
- static __one __test(const volatile binary_function<_T1, _T2, _Res>*);
-
- // It's tempting to change "..." to const volatile void*, but
- // that fails when _Tp is a function type.
- static __two __test(...);
-
- public:
- static const bool value = sizeof(__test((_Tp*)0)) == 1;
- };
-
- /// Turns a function type into a function pointer type
- template<typename _Tp, bool _IsFunctionType = is_function<_Tp>::value>
- struct _Function_to_function_pointer
- {
- typedef _Tp type;
- };
-
- template<typename _Tp>
- struct _Function_to_function_pointer<_Tp, true>
- {
- typedef _Tp* type;
- };
-
- /**
- * Invoke a function object, which may be either a member pointer or a
- * function object. The first parameter will tell which.
- */
- template<typename _Functor, typename... _Args>
- inline
- typename __gnu_cxx::__enable_if<
- (!is_member_pointer<_Functor>::value
- && !is_function<_Functor>::value
- && !is_function<typename remove_pointer<_Functor>::type>::value),
- typename result_of<_Functor(_Args...)>::type
- >::__type
- __invoke(_Functor& __f, _Args&... __args)
- {
- return __f(__args...);
- }
-
- template<typename _Functor, typename... _Args>
- inline
- typename __gnu_cxx::__enable_if<
- (is_member_pointer<_Functor>::value
- && !is_function<_Functor>::value
- && !is_function<typename remove_pointer<_Functor>::type>::value),
- typename result_of<_Functor(_Args...)>::type
- >::__type
- __invoke(_Functor& __f, _Args&... __args)
- {
- return mem_fn(__f)(__args...);
- }
-
- // To pick up function references (that will become function pointers)
- template<typename _Functor, typename... _Args>
- inline
- typename __gnu_cxx::__enable_if<
- (is_pointer<_Functor>::value
- && is_function<typename remove_pointer<_Functor>::type>::value),
- typename result_of<_Functor(_Args...)>::type
- >::__type
- __invoke(_Functor __f, _Args&... __args)
- {
- return __f(__args...);
- }
-
- /**
- * Knowing which of unary_function and binary_function _Tp derives
- * from, derives from the same and ensures that reference_wrapper
- * will have a weak result type. See cases below.
- */
- template<bool _Unary, bool _Binary, typename _Tp>
- struct _Reference_wrapper_base_impl;
-
- // Not a unary_function or binary_function, so try a weak result type.
- template<typename _Tp>
- struct _Reference_wrapper_base_impl<false, false, _Tp>
- : _Weak_result_type<_Tp>
- { };
-
- // unary_function but not binary_function
- template<typename _Tp>
- struct _Reference_wrapper_base_impl<true, false, _Tp>
- : unary_function<typename _Tp::argument_type,
- typename _Tp::result_type>
- { };
-
- // binary_function but not unary_function
- template<typename _Tp>
- struct _Reference_wrapper_base_impl<false, true, _Tp>
- : binary_function<typename _Tp::first_argument_type,
- typename _Tp::second_argument_type,
- typename _Tp::result_type>
- { };
-
- // Both unary_function and binary_function. Import result_type to
- // avoid conflicts.
- template<typename _Tp>
- struct _Reference_wrapper_base_impl<true, true, _Tp>
- : unary_function<typename _Tp::argument_type,
- typename _Tp::result_type>,
- binary_function<typename _Tp::first_argument_type,
- typename _Tp::second_argument_type,
- typename _Tp::result_type>
- {
- typedef typename _Tp::result_type result_type;
- };
-
- /**
- * Derives from unary_function or binary_function when it
- * can. Specializations handle all of the easy cases. The primary
- * template determines what to do with a class type, which may
- * derive from both unary_function and binary_function.
- */
- template<typename _Tp>
- struct _Reference_wrapper_base
- : _Reference_wrapper_base_impl<
- _Derives_from_unary_function<_Tp>::value,
- _Derives_from_binary_function<_Tp>::value,
- _Tp>
- { };
-
- // - a function type (unary)
- template<typename _Res, typename _T1>
- struct _Reference_wrapper_base<_Res(_T1)>
- : unary_function<_T1, _Res>
- { };
-
- // - a function type (binary)
- template<typename _Res, typename _T1, typename _T2>
- struct _Reference_wrapper_base<_Res(_T1, _T2)>
- : binary_function<_T1, _T2, _Res>
- { };
-
- // - a function pointer type (unary)
- template<typename _Res, typename _T1>
- struct _Reference_wrapper_base<_Res(*)(_T1)>
- : unary_function<_T1, _Res>
- { };
-
- // - a function pointer type (binary)
- template<typename _Res, typename _T1, typename _T2>
- struct _Reference_wrapper_base<_Res(*)(_T1, _T2)>
- : binary_function<_T1, _T2, _Res>
- { };
-
- // - a pointer to member function type (unary, no qualifiers)
- template<typename _Res, typename _T1>
- struct _Reference_wrapper_base<_Res (_T1::*)()>
- : unary_function<_T1*, _Res>
- { };
-
- // - a pointer to member function type (binary, no qualifiers)
- template<typename _Res, typename _T1, typename _T2>
- struct _Reference_wrapper_base<_Res (_T1::*)(_T2)>
- : binary_function<_T1*, _T2, _Res>
- { };
-
- // - a pointer to member function type (unary, const)
- template<typename _Res, typename _T1>
- struct _Reference_wrapper_base<_Res (_T1::*)() const>
- : unary_function<const _T1*, _Res>
- { };
-
- // - a pointer to member function type (binary, const)
- template<typename _Res, typename _T1, typename _T2>
- struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const>
- : binary_function<const _T1*, _T2, _Res>
- { };
-
- // - a pointer to member function type (unary, volatile)
- template<typename _Res, typename _T1>
- struct _Reference_wrapper_base<_Res (_T1::*)() volatile>
- : unary_function<volatile _T1*, _Res>
- { };
-
- // - a pointer to member function type (binary, volatile)
- template<typename _Res, typename _T1, typename _T2>
- struct _Reference_wrapper_base<_Res (_T1::*)(_T2) volatile>
- : binary_function<volatile _T1*, _T2, _Res>
- { };
-
- // - a pointer to member function type (unary, const volatile)
- template<typename _Res, typename _T1>
- struct _Reference_wrapper_base<_Res (_T1::*)() const volatile>
- : unary_function<const volatile _T1*, _Res>
- { };
-
- // - a pointer to member function type (binary, const volatile)
- template<typename _Res, typename _T1, typename _T2>
- struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const volatile>
- : binary_function<const volatile _T1*, _T2, _Res>
- { };
-
- /// reference_wrapper
- template<typename _Tp>
- class reference_wrapper
- : public _Reference_wrapper_base<typename remove_cv<_Tp>::type>
- {
- // If _Tp is a function type, we can't form result_of<_Tp(...)>,
- // so turn it into a function pointer type.
- typedef typename _Function_to_function_pointer<_Tp>::type
- _M_func_type;
-
- _Tp* _M_data;
- public:
- typedef _Tp type;
-
- explicit
- reference_wrapper(_Tp& __indata): _M_data(&__indata)
- { }
-
- reference_wrapper(const reference_wrapper<_Tp>& __inref):
- _M_data(__inref._M_data)
- { }
-
- reference_wrapper&
- operator=(const reference_wrapper<_Tp>& __inref)
- {
- _M_data = __inref._M_data;
- return *this;
- }
-
- operator _Tp&() const
- { return this->get(); }
-
- _Tp&
- get() const
- { return *_M_data; }
-
- template<typename... _Args>
- typename result_of<_M_func_type(_Args...)>::type
- operator()(_Args&... __args) const
- {
- return __invoke(get(), __args...);
- }
- };
-
-
- // Denotes a reference should be taken to a variable.
- template<typename _Tp>
- inline reference_wrapper<_Tp>
- ref(_Tp& __t)
- { return reference_wrapper<_Tp>(__t); }
-
- // Denotes a const reference should be taken to a variable.
- template<typename _Tp>
- inline reference_wrapper<const _Tp>
- cref(const _Tp& __t)
- { return reference_wrapper<const _Tp>(__t); }
-
- template<typename _Tp>
- inline reference_wrapper<_Tp>
- ref(reference_wrapper<_Tp> __t)
- { return ref(__t.get()); }
-
- template<typename _Tp>
- inline reference_wrapper<const _Tp>
- cref(reference_wrapper<_Tp> __t)
- { return cref(__t.get()); }
-
- template<typename _Tp, bool>
- struct _Mem_fn_const_or_non
- {
- typedef const _Tp& type;
- };
-
- template<typename _Tp>
- struct _Mem_fn_const_or_non<_Tp, false>
- {
- typedef _Tp& type;
- };
-
- /**
- * Derives from @c unary_function or @c binary_function, or perhaps
- * nothing, depending on the number of arguments provided. The
- * primary template is the basis case, which derives nothing.
- */
- template<typename _Res, typename... _ArgTypes>
- struct _Maybe_unary_or_binary_function { };
-
- /// Derives from @c unary_function, as appropriate.
- template<typename _Res, typename _T1>
- struct _Maybe_unary_or_binary_function<_Res, _T1>
- : std::unary_function<_T1, _Res> { };
-
- /// Derives from @c binary_function, as appropriate.
- template<typename _Res, typename _T1, typename _T2>
- struct _Maybe_unary_or_binary_function<_Res, _T1, _T2>
- : std::binary_function<_T1, _T2, _Res> { };
-
- /// Implementation of @c mem_fn for member function pointers.
- template<typename _Res, typename _Class, typename... _ArgTypes>
- class _Mem_fn<_Res (_Class::*)(_ArgTypes...)>
- : public _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...>
- {
- typedef _Res (_Class::*_Functor)(_ArgTypes...);
-
- template<typename _Tp>
- _Res
- _M_call(_Tp& __object, const volatile _Class *,
- _ArgTypes... __args) const
- { return (__object.*__pmf)(__args...); }
-
- template<typename _Tp>
- _Res
- _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
- { return ((*__ptr).*__pmf)(__args...); }
-
- public:
- typedef _Res result_type;
-
- explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
-
- // Handle objects
- _Res
- operator()(_Class& __object, _ArgTypes... __args) const
- { return (__object.*__pmf)(__args...); }
-
- // Handle pointers
- _Res
- operator()(_Class* __object, _ArgTypes... __args) const
- { return (__object->*__pmf)(__args...); }
-
- // Handle smart pointers, references and pointers to derived
- template<typename _Tp>
- _Res
- operator()(_Tp& __object, _ArgTypes... __args) const
- { return _M_call(__object, &__object, __args...); }
-
- private:
- _Functor __pmf;
- };
-
- /// Implementation of @c mem_fn for const member function pointers.
- template<typename _Res, typename _Class, typename... _ArgTypes>
- class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const>
- : public _Maybe_unary_or_binary_function<_Res, const _Class*,
- _ArgTypes...>
- {
- typedef _Res (_Class::*_Functor)(_ArgTypes...) const;
-
- template<typename _Tp>
- _Res
- _M_call(_Tp& __object, const volatile _Class *,
- _ArgTypes... __args) const
- { return (__object.*__pmf)(__args...); }
-
- template<typename _Tp>
- _Res
- _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
- { return ((*__ptr).*__pmf)(__args...); }
-
- public:
- typedef _Res result_type;
-
- explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
-
- // Handle objects
- _Res
- operator()(const _Class& __object, _ArgTypes... __args) const
- { return (__object.*__pmf)(__args...); }
-
- // Handle pointers
- _Res
- operator()(const _Class* __object, _ArgTypes... __args) const
- { return (__object->*__pmf)(__args...); }
-
- // Handle smart pointers, references and pointers to derived
- template<typename _Tp>
- _Res operator()(_Tp& __object, _ArgTypes... __args) const
- { return _M_call(__object, &__object, __args...); }
-
- private:
- _Functor __pmf;
- };
-
- /// Implementation of @c mem_fn for volatile member function pointers.
- template<typename _Res, typename _Class, typename... _ArgTypes>
- class _Mem_fn<_Res (_Class::*)(_ArgTypes...) volatile>
- : public _Maybe_unary_or_binary_function<_Res, volatile _Class*,
- _ArgTypes...>
- {
- typedef _Res (_Class::*_Functor)(_ArgTypes...) volatile;
-
- template<typename _Tp>
- _Res
- _M_call(_Tp& __object, const volatile _Class *,
- _ArgTypes... __args) const
- { return (__object.*__pmf)(__args...); }
-
- template<typename _Tp>
- _Res
- _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
- { return ((*__ptr).*__pmf)(__args...); }
-
- public:
- typedef _Res result_type;
-
- explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
-
- // Handle objects
- _Res
- operator()(volatile _Class& __object, _ArgTypes... __args) const
- { return (__object.*__pmf)(__args...); }
-
- // Handle pointers
- _Res
- operator()(volatile _Class* __object, _ArgTypes... __args) const
- { return (__object->*__pmf)(__args...); }
-
- // Handle smart pointers, references and pointers to derived
- template<typename _Tp>
- _Res
- operator()(_Tp& __object, _ArgTypes... __args) const
- { return _M_call(__object, &__object, __args...); }
-
- private:
- _Functor __pmf;
- };
-
- /// Implementation of @c mem_fn for const volatile member function pointers.
- template<typename _Res, typename _Class, typename... _ArgTypes>
- class _Mem_fn<_Res (_Class::*)(_ArgTypes...) const volatile>
- : public _Maybe_unary_or_binary_function<_Res, const volatile _Class*,
- _ArgTypes...>
- {
- typedef _Res (_Class::*_Functor)(_ArgTypes...) const volatile;
-
- template<typename _Tp>
- _Res
- _M_call(_Tp& __object, const volatile _Class *,
- _ArgTypes... __args) const
- { return (__object.*__pmf)(__args...); }
-
- template<typename _Tp>
- _Res
- _M_call(_Tp& __ptr, const volatile void *, _ArgTypes... __args) const
- { return ((*__ptr).*__pmf)(__args...); }
-
- public:
- typedef _Res result_type;
-
- explicit _Mem_fn(_Functor __pmf) : __pmf(__pmf) { }
-
- // Handle objects
- _Res
- operator()(const volatile _Class& __object, _ArgTypes... __args) const
- { return (__object.*__pmf)(__args...); }
-
- // Handle pointers
- _Res
- operator()(const volatile _Class* __object, _ArgTypes... __args) const
- { return (__object->*__pmf)(__args...); }
-
- // Handle smart pointers, references and pointers to derived
- template<typename _Tp>
- _Res operator()(_Tp& __object, _ArgTypes... __args) const
- { return _M_call(__object, &__object, __args...); }
-
- private:
- _Functor __pmf;
- };
-
-
- template<typename _Res, typename _Class>
- class _Mem_fn<_Res _Class::*>
- {
- // This bit of genius is due to Peter Dimov, improved slightly by
- // Douglas Gregor.
- template<typename _Tp>
- _Res&
- _M_call(_Tp& __object, _Class *) const
- { return __object.*__pm; }
-
- template<typename _Tp, typename _Up>
- _Res&
- _M_call(_Tp& __object, _Up * const *) const
- { return (*__object).*__pm; }
-
- template<typename _Tp, typename _Up>
- const _Res&
- _M_call(_Tp& __object, const _Up * const *) const
- { return (*__object).*__pm; }
-
- template<typename _Tp>
- const _Res&
- _M_call(_Tp& __object, const _Class *) const
- { return __object.*__pm; }
-
- template<typename _Tp>
- const _Res&
- _M_call(_Tp& __ptr, const volatile void*) const
- { return (*__ptr).*__pm; }
-
- template<typename _Tp> static _Tp& __get_ref();
-
- template<typename _Tp>
- static __sfinae_types::__one __check_const(_Tp&, _Class*);
- template<typename _Tp, typename _Up>
- static __sfinae_types::__one __check_const(_Tp&, _Up * const *);
- template<typename _Tp, typename _Up>
- static __sfinae_types::__two __check_const(_Tp&, const _Up * const *);
- template<typename _Tp>
- static __sfinae_types::__two __check_const(_Tp&, const _Class*);
- template<typename _Tp>
- static __sfinae_types::__two __check_const(_Tp&, const volatile void*);
-
- public:
- template<typename _Tp>
- struct _Result_type
- : _Mem_fn_const_or_non<_Res,
- (sizeof(__sfinae_types::__two)
- == sizeof(__check_const<_Tp>(__get_ref<_Tp>(), (_Tp*)0)))>
- { };
-
- template<typename _Signature>
- struct result;
-
- template<typename _CVMem, typename _Tp>
- struct result<_CVMem(_Tp)>
- : public _Result_type<_Tp> { };
-
- template<typename _CVMem, typename _Tp>
- struct result<_CVMem(_Tp&)>
- : public _Result_type<_Tp> { };
-
- explicit
- _Mem_fn(_Res _Class::*__pm) : __pm(__pm) { }
-
- // Handle objects
- _Res&
- operator()(_Class& __object) const
- { return __object.*__pm; }
-
- const _Res&
- operator()(const _Class& __object) const
- { return __object.*__pm; }
-
- // Handle pointers
- _Res&
- operator()(_Class* __object) const
- { return __object->*__pm; }
-
- const _Res&
- operator()(const _Class* __object) const
- { return __object->*__pm; }
-
- // Handle smart pointers and derived
- template<typename _Tp>
- typename _Result_type<_Tp>::type
- operator()(_Tp& __unknown) const
- { return _M_call(__unknown, &__unknown); }
-
- private:
- _Res _Class::*__pm;
- };
-
- /**
- * @brief Returns a function object that forwards to the member
- * pointer @a pm.
- */
- template<typename _Tp, typename _Class>
- inline _Mem_fn<_Tp _Class::*>
- mem_fn(_Tp _Class::* __pm)
- {
- return _Mem_fn<_Tp _Class::*>(__pm);
- }
-
- /**
- * @brief Determines if the given type _Tp is a function object
- * should be treated as a subexpression when evaluating calls to
- * function objects returned by bind(). [TR1 3.6.1]
- */
- template<typename _Tp>
- struct is_bind_expression
- { static const bool value = false; };
-
- template<typename _Tp>
- const bool is_bind_expression<_Tp>::value;
-
- /**
- * @brief Determines if the given type _Tp is a placeholder in a
- * bind() expression and, if so, which placeholder it is. [TR1 3.6.2]
- */
- template<typename _Tp>
- struct is_placeholder
- { static const int value = 0; };
-
- template<typename _Tp>
- const int is_placeholder<_Tp>::value;
-
- /// The type of placeholder objects defined by libstdc++.
- template<int _Num> struct _Placeholder { };
-
- /** @namespace std::placeholders
- * @brief ISO C++ 0x entities sub namespace for functional.
- *
- * Define a large number of placeholders. There is no way to
- * simplify this with variadic templates, because we're introducing
- * unique names for each.
- */
- namespace placeholders
- {
- namespace
- {
- _Placeholder<1> _1;
- _Placeholder<2> _2;
- _Placeholder<3> _3;
- _Placeholder<4> _4;
- _Placeholder<5> _5;
- _Placeholder<6> _6;
- _Placeholder<7> _7;
- _Placeholder<8> _8;
- _Placeholder<9> _9;
- _Placeholder<10> _10;
- _Placeholder<11> _11;
- _Placeholder<12> _12;
- _Placeholder<13> _13;
- _Placeholder<14> _14;
- _Placeholder<15> _15;
- _Placeholder<16> _16;
- _Placeholder<17> _17;
- _Placeholder<18> _18;
- _Placeholder<19> _19;
- _Placeholder<20> _20;
- _Placeholder<21> _21;
- _Placeholder<22> _22;
- _Placeholder<23> _23;
- _Placeholder<24> _24;
- _Placeholder<25> _25;
- _Placeholder<26> _26;
- _Placeholder<27> _27;
- _Placeholder<28> _28;
- _Placeholder<29> _29;
- }
- }
-
- /**
- * Partial specialization of is_placeholder that provides the placeholder
- * number for the placeholder objects defined by libstdc++.
- */
- template<int _Num>
- struct is_placeholder<_Placeholder<_Num> >
- { static const int value = _Num; };
-
- template<int _Num>
- const int is_placeholder<_Placeholder<_Num> >::value;
-
- /**
- * Stores a tuple of indices. Used by bind() to extract the elements
- * in a tuple.
- */
- template<int... _Indexes>
- struct _Index_tuple { };
-
- /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
- template<std::size_t _Num, typename _Tuple = _Index_tuple<> >
- struct _Build_index_tuple;
-
- template<std::size_t _Num, int... _Indexes>
- struct _Build_index_tuple<_Num, _Index_tuple<_Indexes...> >
- : _Build_index_tuple<_Num - 1,
- _Index_tuple<_Indexes..., sizeof...(_Indexes)> >
- {
- };
-
- template<int... _Indexes>
- struct _Build_index_tuple<0, _Index_tuple<_Indexes...> >
- {
- typedef _Index_tuple<_Indexes...> __type;
- };
-
- /**
- * Used by _Safe_tuple_element to indicate that there is no tuple
- * element at this position.
- */
- struct _No_tuple_element;
-
- /**
- * Implementation helper for _Safe_tuple_element. This primary
- * template handles the case where it is safe to use @c
- * tuple_element.
- */
- template<int __i, typename _Tuple, bool _IsSafe>
- struct _Safe_tuple_element_impl
- : tuple_element<__i, _Tuple> { };
-
- /**
- * Implementation helper for _Safe_tuple_element. This partial
- * specialization handles the case where it is not safe to use @c
- * tuple_element. We just return @c _No_tuple_element.
- */
- template<int __i, typename _Tuple>
- struct _Safe_tuple_element_impl<__i, _Tuple, false>
- {
- typedef _No_tuple_element type;
- };
-
- /**
- * Like tuple_element, but returns @c _No_tuple_element when
- * tuple_element would return an error.
- */
- template<int __i, typename _Tuple>
- struct _Safe_tuple_element
- : _Safe_tuple_element_impl<__i, _Tuple,
- (__i >= 0 && __i < tuple_size<_Tuple>::value)>
- {
- };
-
- /**
- * Maps an argument to bind() into an actual argument to the bound
- * function object [TR1 3.6.3/5]. Only the first parameter should
- * be specified: the rest are used to determine among the various
- * implementations. Note that, although this class is a function
- * object, it isn't entirely normal because it takes only two
- * parameters regardless of the number of parameters passed to the
- * bind expression. The first parameter is the bound argument and
- * the second parameter is a tuple containing references to the
- * rest of the arguments.
- */
- template<typename _Arg,
- bool _IsBindExp = is_bind_expression<_Arg>::value,
- bool _IsPlaceholder = (is_placeholder<_Arg>::value > 0)>
- class _Mu;
-
- /**
- * If the argument is reference_wrapper<_Tp>, returns the
- * underlying reference. [TR1 3.6.3/5 bullet 1]
- */
- template<typename _Tp>
- class _Mu<reference_wrapper<_Tp>, false, false>
- {
- public:
- typedef _Tp& result_type;
-
- /* Note: This won't actually work for const volatile
- * reference_wrappers, because reference_wrapper::get() is const
- * but not volatile-qualified. This might be a defect in the TR.
- */
- template<typename _CVRef, typename _Tuple>
- result_type
- operator()(_CVRef& __arg, const _Tuple&) const volatile
- { return __arg.get(); }
- };
-
- /**
- * If the argument is a bind expression, we invoke the underlying
- * function object with the same cv-qualifiers as we are given and
- * pass along all of our arguments (unwrapped). [TR1 3.6.3/5 bullet 2]
- */
- template<typename _Arg>
- class _Mu<_Arg, true, false>
- {
- public:
- template<typename _Signature> class result;
-
- // Determine the result type when we pass the arguments along. This
- // involves passing along the cv-qualifiers placed on _Mu and
- // unwrapping the argument bundle.
- template<typename _CVMu, typename _CVArg, typename... _Args>
- class result<_CVMu(_CVArg, tuple<_Args...>)>
- : public result_of<_CVArg(_Args...)> { };
-
- template<typename _CVArg, typename... _Args>
- typename result_of<_CVArg(_Args...)>::type
- operator()(_CVArg& __arg,
- const tuple<_Args...>& __tuple) const volatile
- {
- // Construct an index tuple and forward to __call
- typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
- _Indexes;
- return this->__call(__arg, __tuple, _Indexes());
- }
-
- private:
- // Invokes the underlying function object __arg by unpacking all
- // of the arguments in the tuple.
- template<typename _CVArg, typename... _Args, int... _Indexes>
- typename result_of<_CVArg(_Args...)>::type
- __call(_CVArg& __arg, const tuple<_Args...>& __tuple,
- const _Index_tuple<_Indexes...>&) const volatile
- {
- return __arg(_GLIBCXX_TR1 get<_Indexes>(__tuple)...);
- }
- };
-
- /**
- * If the argument is a placeholder for the Nth argument, returns
- * a reference to the Nth argument to the bind function object.
- * [TR1 3.6.3/5 bullet 3]
- */
- template<typename _Arg>
- class _Mu<_Arg, false, true>
- {
- public:
- template<typename _Signature> class result;
-
- template<typename _CVMu, typename _CVArg, typename _Tuple>
- class result<_CVMu(_CVArg, _Tuple)>
- {
- // Add a reference, if it hasn't already been done for us.
- // This allows us to be a little bit sloppy in constructing
- // the tuple that we pass to result_of<...>.
- typedef typename _Safe_tuple_element<(is_placeholder<_Arg>::value
- - 1), _Tuple>::type
- __base_type;
-
- public:
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
- typedef typename add_lvalue_reference<__base_type>::type type;
-#else
- typedef typename add_reference<__base_type>::type type;
-#endif
- };
-
- template<typename _Tuple>
- typename result<_Mu(_Arg, _Tuple)>::type
- operator()(const volatile _Arg&, const _Tuple& __tuple) const volatile
- {
- return ::std::_GLIBCXX_TR1 get<(is_placeholder<_Arg>::value
- - 1)>(__tuple);
- }
- };
-
- /**
- * If the argument is just a value, returns a reference to that
- * value. The cv-qualifiers on the reference are the same as the
- * cv-qualifiers on the _Mu object. [TR1 3.6.3/5 bullet 4]
- */
- template<typename _Arg>
- class _Mu<_Arg, false, false>
- {
- public:
- template<typename _Signature> struct result;
-
- template<typename _CVMu, typename _CVArg, typename _Tuple>
- struct result<_CVMu(_CVArg, _Tuple)>
- {
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
- typedef typename add_lvalue_reference<_CVArg>::type type;
-#else
- typedef typename add_reference<_CVArg>::type type;
-#endif
- };
-
- // Pick up the cv-qualifiers of the argument
- template<typename _CVArg, typename _Tuple>
- _CVArg&
- operator()(_CVArg& __arg, const _Tuple&) const volatile
- { return __arg; }
- };
-
- /**
- * Maps member pointers into instances of _Mem_fn but leaves all
- * other function objects untouched. Used by tr1::bind(). The
- * primary template handles the non--member-pointer case.
- */
- template<typename _Tp>
- struct _Maybe_wrap_member_pointer
- {
- typedef _Tp type;
-
- static const _Tp&
- __do_wrap(const _Tp& __x)
- { return __x; }
- };
-
- /**
- * Maps member pointers into instances of _Mem_fn but leaves all
- * other function objects untouched. Used by tr1::bind(). This
- * partial specialization handles the member pointer case.
- */
- template<typename _Tp, typename _Class>
- struct _Maybe_wrap_member_pointer<_Tp _Class::*>
- {
- typedef _Mem_fn<_Tp _Class::*> type;
-
- static type
- __do_wrap(_Tp _Class::* __pm)
- { return type(__pm); }
- };
-
- /// Type of the function object returned from bind().
- template<typename _Signature>
- struct _Bind;
-
- template<typename _Functor, typename... _Bound_args>
- class _Bind<_Functor(_Bound_args...)>
- : public _Weak_result_type<_Functor>
- {
- typedef _Bind __self_type;
- typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type
- _Bound_indexes;
-
- _Functor _M_f;
- tuple<_Bound_args...> _M_bound_args;
-
- // Call unqualified
- template<typename... _Args, int... _Indexes>
- typename result_of<
- _Functor(typename result_of<_Mu<_Bound_args>
- (_Bound_args, tuple<_Args...>)>::type...)
- >::type
- __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>)
- {
- return _M_f(_Mu<_Bound_args>()
- (_GLIBCXX_TR1 get<_Indexes>(_M_bound_args), __args)...);
- }
-
- // Call as const
- template<typename... _Args, int... _Indexes>
- typename result_of<
- const _Functor(typename result_of<_Mu<_Bound_args>
- (const _Bound_args, tuple<_Args...>)
- >::type...)>::type
- __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) const
- {
- return _M_f(_Mu<_Bound_args>()
- (_GLIBCXX_TR1 get<_Indexes>(_M_bound_args), __args)...);
- }
-
- // Call as volatile
- template<typename... _Args, int... _Indexes>
- typename result_of<
- volatile _Functor(typename result_of<_Mu<_Bound_args>
- (volatile _Bound_args, tuple<_Args...>)
- >::type...)>::type
- __call(const tuple<_Args...>& __args,
- _Index_tuple<_Indexes...>) volatile
- {
- return _M_f(_Mu<_Bound_args>()
- (_GLIBCXX_TR1 get<_Indexes>(_M_bound_args), __args)...);
- }
-
- // Call as const volatile
- template<typename... _Args, int... _Indexes>
- typename result_of<
- const volatile _Functor(typename result_of<_Mu<_Bound_args>
- (const volatile _Bound_args,
- tuple<_Args...>)
- >::type...)>::type
- __call(const tuple<_Args...>& __args,
- _Index_tuple<_Indexes...>) const volatile
- {
- return _M_f(_Mu<_Bound_args>()
- (_GLIBCXX_TR1 get<_Indexes>(_M_bound_args), __args)...);
- }
-
- public:
- explicit _Bind(_Functor __f, _Bound_args... __bound_args)
- : _M_f(__f), _M_bound_args(__bound_args...) { }
-
- // Call unqualified
- template<typename... _Args>
- typename result_of<
- _Functor(typename result_of<_Mu<_Bound_args>
- (_Bound_args, tuple<_Args...>)>::type...)
- >::type
- operator()(_Args&... __args)
- {
- return this->__call(_GLIBCXX_TR1 tie(__args...), _Bound_indexes());
- }
-
- // Call as const
- template<typename... _Args>
- typename result_of<
- const _Functor(typename result_of<_Mu<_Bound_args>
- (const _Bound_args, tuple<_Args...>)>::type...)
- >::type
- operator()(_Args&... __args) const
- {
- return this->__call(_GLIBCXX_TR1 tie(__args...), _Bound_indexes());
- }
-
-
- // Call as volatile
- template<typename... _Args>
- typename result_of<
- volatile _Functor(typename result_of<_Mu<_Bound_args>
- (volatile _Bound_args, tuple<_Args...>)>::type...)
- >::type
- operator()(_Args&... __args) volatile
- {
- return this->__call(_GLIBCXX_TR1 tie(__args...), _Bound_indexes());
- }
-
-
- // Call as const volatile
- template<typename... _Args>
- typename result_of<
- const volatile _Functor(typename result_of<_Mu<_Bound_args>
- (const volatile _Bound_args,
- tuple<_Args...>)>::type...)
- >::type
- operator()(_Args&... __args) const volatile
- {
- return this->__call(_GLIBCXX_TR1 tie(__args...), _Bound_indexes());
- }
- };
-
- /// Type of the function object returned from bind<R>().
- template<typename _Result, typename _Signature>
- struct _Bind_result;
-
- template<typename _Result, typename _Functor, typename... _Bound_args>
- class _Bind_result<_Result, _Functor(_Bound_args...)>
- {
- typedef _Bind_result __self_type;
- typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type
- _Bound_indexes;
-
- _Functor _M_f;
- tuple<_Bound_args...> _M_bound_args;
-
- // Call unqualified
- template<typename... _Args, int... _Indexes>
- _Result
- __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>)
- {
- return _M_f(_Mu<_Bound_args>()
- (_GLIBCXX_TR1 get<_Indexes>(_M_bound_args), __args)...);
- }
-
- // Call as const
- template<typename... _Args, int... _Indexes>
- _Result
- __call(const tuple<_Args...>& __args, _Index_tuple<_Indexes...>) const
- {
- return _M_f(_Mu<_Bound_args>()
- (_GLIBCXX_TR1 get<_Indexes>(_M_bound_args), __args)...);
- }
-
- // Call as volatile
- template<typename... _Args, int... _Indexes>
- _Result
- __call(const tuple<_Args...>& __args,
- _Index_tuple<_Indexes...>) volatile
- {
- return _M_f(_Mu<_Bound_args>()
- (_GLIBCXX_TR1 get<_Indexes>(_M_bound_args), __args)...);
- }
-
- // Call as const volatile
- template<typename... _Args, int... _Indexes>
- _Result
- __call(const tuple<_Args...>& __args,
- _Index_tuple<_Indexes...>) const volatile
- {
- return _M_f(_Mu<_Bound_args>()
- (_GLIBCXX_TR1 get<_Indexes>(_M_bound_args), __args)...);
- }
-
- public:
- typedef _Result result_type;
-
- explicit
- _Bind_result(_Functor __f, _Bound_args... __bound_args)
- : _M_f(__f), _M_bound_args(__bound_args...) { }
-
- // Call unqualified
- template<typename... _Args>
- result_type
- operator()(_Args&... __args)
- {
- return this->__call(_GLIBCXX_TR1 tie(__args...), _Bound_indexes());
- }
-
- // Call as const
- template<typename... _Args>
- result_type
- operator()(_Args&... __args) const
- {
- return this->__call(_GLIBCXX_TR1 tie(__args...), _Bound_indexes());
- }
-
- // Call as volatile
- template<typename... _Args>
- result_type
- operator()(_Args&... __args) volatile
- {
- return this->__call(_GLIBCXX_TR1 tie(__args...), _Bound_indexes());
- }
-
- // Call as const volatile
- template<typename... _Args>
- result_type
- operator()(_Args&... __args) const volatile
- {
- return this->__call(_GLIBCXX_TR1 tie(__args...), _Bound_indexes());
- }
- };
-
- /// Class template _Bind is always a bind expression.
- template<typename _Signature>
- struct is_bind_expression<_Bind<_Signature> >
- { static const bool value = true; };
-
- template<typename _Signature>
- const bool is_bind_expression<_Bind<_Signature> >::value;
-
- /// Class template _Bind_result is always a bind expression.
- template<typename _Result, typename _Signature>
- struct is_bind_expression<_Bind_result<_Result, _Signature> >
- { static const bool value = true; };
-
- template<typename _Result, typename _Signature>
- const bool is_bind_expression<_Bind_result<_Result, _Signature> >::value;
-
- /// bind
- template<typename _Functor, typename... _ArgTypes>
- inline
- _Bind<typename _Maybe_wrap_member_pointer<_Functor>::type(_ArgTypes...)>
- bind(_Functor __f, _ArgTypes... __args)
- {
- typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
- typedef typename __maybe_type::type __functor_type;
- typedef _Bind<__functor_type(_ArgTypes...)> __result_type;
- return __result_type(__maybe_type::__do_wrap(__f), __args...);
- }
-
- template<typename _Result, typename _Functor, typename... _ArgTypes>
- inline
- _Bind_result<_Result,
- typename _Maybe_wrap_member_pointer<_Functor>::type
- (_ArgTypes...)>
- bind(_Functor __f, _ArgTypes... __args)
- {
- typedef _Maybe_wrap_member_pointer<_Functor> __maybe_type;
- typedef typename __maybe_type::type __functor_type;
- typedef _Bind_result<_Result, __functor_type(_ArgTypes...)>
- __result_type;
- return __result_type(__maybe_type::__do_wrap(__f), __args...);
- }
-
- /**
- * @brief Exception class thrown when class template function's
- * operator() is called with an empty target.
- * @ingroup exceptions
- */
- class bad_function_call : public std::exception { };
-
- /**
- * The integral constant expression 0 can be converted into a
- * pointer to this type. It is used by the function template to
- * accept NULL pointers.
- */
- struct _M_clear_type;
-
- /**
- * Trait identifying "location-invariant" types, meaning that the
- * address of the object (or any of its members) will not escape.
- * Also implies a trivial copy constructor and assignment operator.
- */
- template<typename _Tp>
- struct __is_location_invariant
- : integral_constant<bool,
- (is_pointer<_Tp>::value
- || is_member_pointer<_Tp>::value)>
- {
- };
-
- class _Undefined_class;
-
- union _Nocopy_types
- {
- void* _M_object;
- const void* _M_const_object;
- void (*_M_function_pointer)();
- void (_Undefined_class::*_M_member_pointer)();
- };
-
- union _Any_data
- {
- void* _M_access() { return &_M_pod_data[0]; }
- const void* _M_access() const { return &_M_pod_data[0]; }
-
- template<typename _Tp>
- _Tp&
- _M_access()
- { return *static_cast<_Tp*>(_M_access()); }
-
- template<typename _Tp>
- const _Tp&
- _M_access() const
- { return *static_cast<const _Tp*>(_M_access()); }
-
- _Nocopy_types _M_unused;
- char _M_pod_data[sizeof(_Nocopy_types)];
- };
-
- enum _Manager_operation
- {
- __get_type_info,
- __get_functor_ptr,
- __clone_functor,
- __destroy_functor
- };
-
- // Simple type wrapper that helps avoid annoying const problems
- // when casting between void pointers and pointers-to-pointers.
- template<typename _Tp>
- struct _Simple_type_wrapper
- {
- _Simple_type_wrapper(_Tp __value) : __value(__value) { }
-
- _Tp __value;
- };
-
- template<typename _Tp>
- struct __is_location_invariant<_Simple_type_wrapper<_Tp> >
- : __is_location_invariant<_Tp>
- {
- };
-
- // Converts a reference to a function object into a callable
- // function object.
- template<typename _Functor>
- inline _Functor&
- __callable_functor(_Functor& __f)
- { return __f; }
-
- template<typename _Member, typename _Class>
- inline _Mem_fn<_Member _Class::*>
- __callable_functor(_Member _Class::* &__p)
- { return mem_fn(__p); }
-
- template<typename _Member, typename _Class>
- inline _Mem_fn<_Member _Class::*>
- __callable_functor(_Member _Class::* const &__p)
- { return mem_fn(__p); }
-
- template<typename _Signature>
- class function;
-
- /// Base class of all polymorphic function object wrappers.
- class _Function_base
- {
- public:
- static const std::size_t _M_max_size = sizeof(_Nocopy_types);
- static const std::size_t _M_max_align = __alignof__(_Nocopy_types);
-
- template<typename _Functor>
- class _Base_manager
- {
- protected:
- static const bool __stored_locally =
- (__is_location_invariant<_Functor>::value
- && sizeof(_Functor) <= _M_max_size
- && __alignof__(_Functor) <= _M_max_align
- && (_M_max_align % __alignof__(_Functor) == 0));
-
- typedef integral_constant<bool, __stored_locally> _Local_storage;
-
- // Retrieve a pointer to the function object
- static _Functor*
- _M_get_pointer(const _Any_data& __source)
- {
- const _Functor* __ptr =
- __stored_locally? &__source._M_access<_Functor>()
- /* have stored a pointer */ : __source._M_access<_Functor*>();
- return const_cast<_Functor*>(__ptr);
- }
-
- // Clone a location-invariant function object that fits within
- // an _Any_data structure.
- static void
- _M_clone(_Any_data& __dest, const _Any_data& __source, true_type)
- {
- new (__dest._M_access()) _Functor(__source._M_access<_Functor>());
- }
-
- // Clone a function object that is not location-invariant or
- // that cannot fit into an _Any_data structure.
- static void
- _M_clone(_Any_data& __dest, const _Any_data& __source, false_type)
- {
- __dest._M_access<_Functor*>() =
- new _Functor(*__source._M_access<_Functor*>());
- }
-
- // Destroying a location-invariant object may still require
- // destruction.
- static void
- _M_destroy(_Any_data& __victim, true_type)
- {
- __victim._M_access<_Functor>().~_Functor();
- }
-
- // Destroying an object located on the heap.
- static void
- _M_destroy(_Any_data& __victim, false_type)
- {
- delete __victim._M_access<_Functor*>();
- }
-
- public:
- static bool
- _M_manager(_Any_data& __dest, const _Any_data& __source,
- _Manager_operation __op)
- {
- switch (__op)
- {
-#ifdef __GXX_RTTI
- case __get_type_info:
- __dest._M_access<const type_info*>() = &typeid(_Functor);
- break;
-#endif
- case __get_functor_ptr:
- __dest._M_access<_Functor*>() = _M_get_pointer(__source);
- break;
-
- case __clone_functor:
- _M_clone(__dest, __source, _Local_storage());
- break;
-
- case __destroy_functor:
- _M_destroy(__dest, _Local_storage());
- break;
- }
- return false;
- }
-
- static void
- _M_init_functor(_Any_data& __functor, const _Functor& __f)
- { _M_init_functor(__functor, __f, _Local_storage()); }
-
- template<typename _Signature>
- static bool
- _M_not_empty_function(const function<_Signature>& __f)
- { return static_cast<bool>(__f); }
-
- template<typename _Tp>
- static bool
- _M_not_empty_function(const _Tp*& __fp)
- { return __fp; }
-
- template<typename _Class, typename _Tp>
- static bool
- _M_not_empty_function(_Tp _Class::* const& __mp)
- { return __mp; }
-
- template<typename _Tp>
- static bool
- _M_not_empty_function(const _Tp&)
- { return true; }
-
- private:
- static void
- _M_init_functor(_Any_data& __functor, const _Functor& __f, true_type)
- { new (__functor._M_access()) _Functor(__f); }
-
- static void
- _M_init_functor(_Any_data& __functor, const _Functor& __f, false_type)
- { __functor._M_access<_Functor*>() = new _Functor(__f); }
- };
-
- template<typename _Functor>
- class _Ref_manager : public _Base_manager<_Functor*>
- {
- typedef _Function_base::_Base_manager<_Functor*> _Base;
-
- public:
- static bool
- _M_manager(_Any_data& __dest, const _Any_data& __source,
- _Manager_operation __op)
- {
- switch (__op)
- {
-#ifdef __GXX_RTTI
- case __get_type_info:
- __dest._M_access<const type_info*>() = &typeid(_Functor);
- break;
-#endif
- case __get_functor_ptr:
- __dest._M_access<_Functor*>() = *_Base::_M_get_pointer(__source);
- return is_const<_Functor>::value;
- break;
-
- default:
- _Base::_M_manager(__dest, __source, __op);
- }
- return false;
- }
-
- static void
- _M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f)
- {
- // TBD: Use address_of function instead.
- _Base::_M_init_functor(__functor, &__f.get());
- }
- };
-
- _Function_base() : _M_manager(0) { }
-
- ~_Function_base()
- {
- if (_M_manager)
- _M_manager(_M_functor, _M_functor, __destroy_functor);
- }
-
-
- bool _M_empty() const { return !_M_manager; }
-
- typedef bool (*_Manager_type)(_Any_data&, const _Any_data&,
- _Manager_operation);
-
- _Any_data _M_functor;
- _Manager_type _M_manager;
- };
-
- template<typename _Signature, typename _Functor>
- class _Function_handler;
-
- template<typename _Res, typename _Functor, typename... _ArgTypes>
- class _Function_handler<_Res(_ArgTypes...), _Functor>
- : public _Function_base::_Base_manager<_Functor>
- {
- typedef _Function_base::_Base_manager<_Functor> _Base;
-
- public:
- static _Res
- _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
- {
- return (*_Base::_M_get_pointer(__functor))(__args...);
- }
- };
-
- template<typename _Functor, typename... _ArgTypes>
- class _Function_handler<void(_ArgTypes...), _Functor>
- : public _Function_base::_Base_manager<_Functor>
- {
- typedef _Function_base::_Base_manager<_Functor> _Base;
-
- public:
- static void
- _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
- {
- (*_Base::_M_get_pointer(__functor))(__args...);
- }
- };
-
- template<typename _Res, typename _Functor, typename... _ArgTypes>
- class _Function_handler<_Res(_ArgTypes...), reference_wrapper<_Functor> >
- : public _Function_base::_Ref_manager<_Functor>
- {
- typedef _Function_base::_Ref_manager<_Functor> _Base;
-
- public:
- static _Res
- _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
- {
- return
- __callable_functor(**_Base::_M_get_pointer(__functor))(__args...);
- }
- };
-
- template<typename _Functor, typename... _ArgTypes>
- class _Function_handler<void(_ArgTypes...), reference_wrapper<_Functor> >
- : public _Function_base::_Ref_manager<_Functor>
- {
- typedef _Function_base::_Ref_manager<_Functor> _Base;
-
- public:
- static void
- _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
- {
- __callable_functor(**_Base::_M_get_pointer(__functor))(__args...);
- }
- };
-
- template<typename _Class, typename _Member, typename _Res,
- typename... _ArgTypes>
- class _Function_handler<_Res(_ArgTypes...), _Member _Class::*>
- : public _Function_handler<void(_ArgTypes...), _Member _Class::*>
- {
- typedef _Function_handler<void(_ArgTypes...), _Member _Class::*>
- _Base;
-
- public:
- static _Res
- _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
- {
- return _GLIBCXX_TR1
- mem_fn(_Base::_M_get_pointer(__functor)->__value)(__args...);
- }
- };
-
- template<typename _Class, typename _Member, typename... _ArgTypes>
- class _Function_handler<void(_ArgTypes...), _Member _Class::*>
- : public _Function_base::_Base_manager<
- _Simple_type_wrapper< _Member _Class::* > >
- {
- typedef _Member _Class::* _Functor;
- typedef _Simple_type_wrapper<_Functor> _Wrapper;
- typedef _Function_base::_Base_manager<_Wrapper> _Base;
-
- public:
- static bool
- _M_manager(_Any_data& __dest, const _Any_data& __source,
- _Manager_operation __op)
- {
- switch (__op)
- {
-#ifdef __GXX_RTTI
- case __get_type_info:
- __dest._M_access<const type_info*>() = &typeid(_Functor);
- break;
-#endif
- case __get_functor_ptr:
- __dest._M_access<_Functor*>() =
- &_Base::_M_get_pointer(__source)->__value;
- break;
-
- default:
- _Base::_M_manager(__dest, __source, __op);
- }
- return false;
- }
-
- static void
- _M_invoke(const _Any_data& __functor, _ArgTypes... __args)
- {
- _GLIBCXX_TR1
- mem_fn(_Base::_M_get_pointer(__functor)->__value)(__args...);
- }
- };
-
- /// class function
- template<typename _Res, typename... _ArgTypes>
- class function<_Res(_ArgTypes...)>
- : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,
- private _Function_base
- {
-#ifndef __GXX_EXPERIMENTAL_CXX0X__
- /// This class is used to implement the safe_bool idiom.
- struct _Hidden_type
- {
- _Hidden_type* _M_bool;
- };
-
- /// This typedef is used to implement the safe_bool idiom.
- typedef _Hidden_type* _Hidden_type::* _Safe_bool;
-#endif
-
- typedef _Res _Signature_type(_ArgTypes...);
-
- struct _Useless { };
-
- public:
- typedef _Res result_type;
-
- // [3.7.2.1] construct/copy/destroy
-
- /**
- * @brief Default construct creates an empty function call wrapper.
- * @post @c !(bool)*this
- */
- function() : _Function_base() { }
-
- /**
- * @brief Default construct creates an empty function call wrapper.
- * @post @c !(bool)*this
- */
- function(_M_clear_type*) : _Function_base() { }
-
- /**
- * @brief %Function copy constructor.
- * @param x A %function object with identical call signature.
- * @pre @c (bool)*this == (bool)x
- *
- * The newly-created %function contains a copy of the target of @a
- * x (if it has one).
- */
- function(const function& __x);
-
- /**
- * @brief Builds a %function that targets a copy of the incoming
- * function object.
- * @param f A %function object that is callable with parameters of
- * type @c T1, @c T2, ..., @c TN and returns a value convertible
- * to @c Res.
- *
- * The newly-created %function object will target a copy of @a
- * f. If @a f is @c reference_wrapper<F>, then this function
- * object will contain a reference to the function object @c
- * f.get(). If @a f is a NULL function pointer or NULL
- * pointer-to-member, the newly-created object will be empty.
- *
- * If @a f is a non-NULL function pointer or an object of type @c
- * reference_wrapper<F>, this function will not throw.
- */
- template<typename _Functor>
- function(_Functor __f,
- typename __gnu_cxx::__enable_if<
- !is_integral<_Functor>::value, _Useless>::__type
- = _Useless());
-
- /**
- * @brief %Function assignment operator.
- * @param x A %function with identical call signature.
- * @post @c (bool)*this == (bool)x
- * @returns @c *this
- *
- * The target of @a x is copied to @c *this. If @a x has no
- * target, then @c *this will be empty.
- *
- * If @a x targets a function pointer or a reference to a function
- * object, then this operation will not throw an exception.
- */
- function&
- operator=(const function& __x)
- {
- function(__x).swap(*this);
- return *this;
- }
-
- /**
- * @brief %Function assignment to zero.
- * @post @c !(bool)*this
- * @returns @c *this
- *
- * The target of @a *this is deallocated, leaving it empty.
- */
- function&
- operator=(_M_clear_type*)
- {
- if (_M_manager)
- {
- _M_manager(_M_functor, _M_functor, __destroy_functor);
- _M_manager = 0;
- _M_invoker = 0;
- }
- return *this;
- }
-
- /**
- * @brief %Function assignment to a new target.
- * @param f A %function object that is callable with parameters of
- * type @c T1, @c T2, ..., @c TN and returns a value convertible
- * to @c Res.
- * @return @c *this
- *
- * This %function object wrapper will target a copy of @a
- * f. If @a f is @c reference_wrapper<F>, then this function
- * object will contain a reference to the function object @c
- * f.get(). If @a f is a NULL function pointer or NULL
- * pointer-to-member, @c this object will be empty.
- *
- * If @a f is a non-NULL function pointer or an object of type @c
- * reference_wrapper<F>, this function will not throw.
- */
- template<typename _Functor>
- typename __gnu_cxx::__enable_if<!is_integral<_Functor>::value,
- function&>::__type
- operator=(_Functor __f)
- {
- function(__f).swap(*this);
- return *this;
- }
-
- // [3.7.2.2] function modifiers
-
- /**
- * @brief Swap the targets of two %function objects.
- * @param f A %function with identical call signature.
- *
- * Swap the targets of @c this function object and @a f. This
- * function will not throw an exception.
- */
- void swap(function& __x)
- {
- _Any_data __old_functor = _M_functor;
- _M_functor = __x._M_functor;
- __x._M_functor = __old_functor;
- _Manager_type __old_manager = _M_manager;
- _M_manager = __x._M_manager;
- __x._M_manager = __old_manager;
- _Invoker_type __old_invoker = _M_invoker;
- _M_invoker = __x._M_invoker;
- __x._M_invoker = __old_invoker;
- }
-
- // [3.7.2.3] function capacity
-
- /**
- * @brief Determine if the %function wrapper has a target.
- *
- * @return @c true when this %function object contains a target,
- * or @c false when it is empty.
- *
- * This function will not throw an exception.
- */
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- explicit operator bool() const
- { return !_M_empty(); }
-#else
- operator _Safe_bool() const
- {
- if (_M_empty())
- return 0;
- else
- return &_Hidden_type::_M_bool;
- }
-#endif
-
- // [3.7.2.4] function invocation
-
- /**
- * @brief Invokes the function targeted by @c *this.
- * @returns the result of the target.
- * @throws bad_function_call when @c !(bool)*this
- *
- * The function call operator invokes the target function object
- * stored by @c this.
- */
- _Res operator()(_ArgTypes... __args) const;
-
-#ifdef __GXX_RTTI
- // [3.7.2.5] function target access
- /**
- * @brief Determine the type of the target of this function object
- * wrapper.
- *
- * @returns the type identifier of the target function object, or
- * @c typeid(void) if @c !(bool)*this.
- *
- * This function will not throw an exception.
- */
- const type_info& target_type() const;
-
- /**
- * @brief Access the stored target function object.
- *
- * @return Returns a pointer to the stored target function object,
- * if @c typeid(Functor).equals(target_type()); otherwise, a NULL
- * pointer.
- *
- * This function will not throw an exception.
- */
- template<typename _Functor> _Functor* target();
-
- /// @overload
- template<typename _Functor> const _Functor* target() const;
-#endif
-
- private:
- // [3.7.2.6] undefined operators
- template<typename _Function>
- void operator==(const function<_Function>&) const;
- template<typename _Function>
- void operator!=(const function<_Function>&) const;
-
- typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...);
- _Invoker_type _M_invoker;
- };
-
- template<typename _Res, typename... _ArgTypes>
- function<_Res(_ArgTypes...)>::
- function(const function& __x)
- : _Function_base()
- {
- if (static_cast<bool>(__x))
- {
- _M_invoker = __x._M_invoker;
- _M_manager = __x._M_manager;
- __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
- }
- }
-
- template<typename _Res, typename... _ArgTypes>
- template<typename _Functor>
- function<_Res(_ArgTypes...)>::
- function(_Functor __f,
- typename __gnu_cxx::__enable_if<
- !is_integral<_Functor>::value, _Useless>::__type)
- : _Function_base()
- {
- typedef _Function_handler<_Signature_type, _Functor> _My_handler;
-
- if (_My_handler::_M_not_empty_function(__f))
- {
- _M_invoker = &_My_handler::_M_invoke;
- _M_manager = &_My_handler::_M_manager;
- _My_handler::_M_init_functor(_M_functor, __f);
- }
- }
-
- template<typename _Res, typename... _ArgTypes>
- _Res
- function<_Res(_ArgTypes...)>::
- operator()(_ArgTypes... __args) const
- {
- if (_M_empty())
- {
-#if __EXCEPTIONS
- throw bad_function_call();
-#else
- __builtin_abort();
-#endif
- }
- return _M_invoker(_M_functor, __args...);
- }
-
-#ifdef __GXX_RTTI
- template<typename _Res, typename... _ArgTypes>
- const type_info&
- function<_Res(_ArgTypes...)>::
- target_type() const
- {
- if (_M_manager)
- {
- _Any_data __typeinfo_result;
- _M_manager(__typeinfo_result, _M_functor, __get_type_info);
- return *__typeinfo_result._M_access<const type_info*>();
- }
- else
- return typeid(void);
- }
-
- template<typename _Res, typename... _ArgTypes>
- template<typename _Functor>
- _Functor*
- function<_Res(_ArgTypes...)>::
- target()
- {
- if (typeid(_Functor) == target_type() && _M_manager)
- {
- _Any_data __ptr;
- if (_M_manager(__ptr, _M_functor, __get_functor_ptr)
- && !is_const<_Functor>::value)
- return 0;
- else
- return __ptr._M_access<_Functor*>();
- }
- else
- return 0;
- }
-
- template<typename _Res, typename... _ArgTypes>
- template<typename _Functor>
- const _Functor*
- function<_Res(_ArgTypes...)>::
- target() const
- {
- if (typeid(_Functor) == target_type() && _M_manager)
- {
- _Any_data __ptr;
- _M_manager(__ptr, _M_functor, __get_functor_ptr);
- return __ptr._M_access<const _Functor*>();
- }
- else
- return 0;
- }
-#endif
-
- // [3.7.2.7] null pointer comparisons
-
- /**
- * @brief Compares a polymorphic function object wrapper against 0
- * (the NULL pointer).
- * @returns @c true if the wrapper has no target, @c false otherwise
- *
- * This function will not throw an exception.
- */
- template<typename _Signature>
- inline bool
- operator==(const function<_Signature>& __f, _M_clear_type*)
- { return !static_cast<bool>(__f); }
-
- /// @overload
- template<typename _Signature>
- inline bool
- operator==(_M_clear_type*, const function<_Signature>& __f)
- { return !static_cast<bool>(__f); }
-
- /**
- * @brief Compares a polymorphic function object wrapper against 0
- * (the NULL pointer).
- * @returns @c false if the wrapper has no target, @c true otherwise
- *
- * This function will not throw an exception.
- */
- template<typename _Signature>
- inline bool
- operator!=(const function<_Signature>& __f, _M_clear_type*)
- { return static_cast<bool>(__f); }
-
- /// @overload
- template<typename _Signature>
- inline bool
- operator!=(_M_clear_type*, const function<_Signature>& __f)
- { return static_cast<bool>(__f); }
-
- // [3.7.2.8] specialized algorithms
-
- /**
- * @brief Swap the targets of two polymorphic function object wrappers.
- *
- * This function will not throw an exception.
- */
- template<typename _Signature>
- inline void
- swap(function<_Signature>& __x, function<_Signature>& __y)
- { __x.swap(__y); }
-
-_GLIBCXX_END_NAMESPACE_TR1
-}
diff --git a/libstdc++-v3/testsuite/20_util/function/assign/move.cc b/libstdc++-v3/testsuite/20_util/function/assign/move.cc
new file mode 100644
index 00000000000..a2ab96245ca
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/function/assign/move.cc
@@ -0,0 +1,50 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <functional>
+#include <testsuite_hooks.h>
+
+int f1() { return 1; }
+struct { int operator()() { return 2; } } f2;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ typedef std::function<int()> function;
+
+ function fo(f1);
+ function fo1;
+ fo1 = (std::move(fo));
+ VERIFY( static_cast<bool>(fo1) );
+ VERIFY( fo1() == 1 );
+
+ fo = function(f2);
+ function fo2;
+ fo2 = (std::move(fo));
+ VERIFY( static_cast<bool>(fo2) );
+ VERIFY( fo2() == 2 );
+}
+
+int main()
+{
+ test01();
+
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/function/cmp/cmp_neg.cc b/libstdc++-v3/testsuite/20_util/function/cmp/cmp_neg.cc
new file mode 100644
index 00000000000..a196ef64e2e
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/function/cmp/cmp_neg.cc
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <functional>
+
+void test01()
+{
+ std::function<void()> f1;
+ std::function<void()> f2;
+ f1 == f2; // { dg-error "here" }
+ f1 != f2; // { dg-error "here" }
+ // { dg-excess-errors "" }
+}
+
+int main()
+{
+ test01();
+
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/function/cons/move.cc b/libstdc++-v3/testsuite/20_util/function/cons/move.cc
new file mode 100644
index 00000000000..43d71858c9f
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/function/cons/move.cc
@@ -0,0 +1,48 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <functional>
+#include <testsuite_hooks.h>
+
+int f1() { return 1; }
+struct { int operator()() { return 2; } } f2;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ typedef std::function<int()> function;
+
+ function fo(f1);
+ function fo1(std::move(fo));
+ VERIFY( static_cast<bool>(fo1) );
+ VERIFY( fo1() == 1 );
+
+ fo = function(f2);
+ function fo2(std::move(fo));
+ VERIFY( static_cast<bool>(fo2) );
+ VERIFY( fo2() == 2 );
+}
+
+int main()
+{
+ test01();
+
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/function/invoke/move_only.cc b/libstdc++-v3/testsuite/20_util/function/invoke/move_only.cc
new file mode 100644
index 00000000000..fbfb0624a00
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/function/invoke/move_only.cc
@@ -0,0 +1,61 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <functional>
+
+struct moveable
+{
+ moveable() = default;
+ ~moveable() = default;
+ moveable(const moveable& c) = delete;
+ moveable& operator=(const moveable&) = delete;
+ moveable(moveable&&) { }
+};
+
+void f1(moveable) { }
+void f2(moveable&&) { }
+struct { void operator()(moveable&&) { } } f3;
+
+void test01()
+{
+ std::function<void (moveable)> fo1a(f1);
+ fo1a(moveable());
+
+ std::function<void (moveable)> fo2a(f2);
+ fo2a(moveable());
+
+ std::function<void (moveable)> fo3a(f3);
+ fo3a(moveable());
+
+ std::function<void (moveable&&)> fo1b(f1);
+ fo1b(moveable());
+
+ std::function<void (moveable&&)> fo2b(f2);
+ fo2b(moveable());
+
+ std::function<void (moveable&&)> fo3b(f3);
+ fo3b(moveable());
+}
+
+int main()
+{
+ test01();
+
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index c71991afc90..9ae652f7328 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -97,6 +97,13 @@ proc libstdc++_init { testfile } {
setenv LC_ALL C
setenv LANG C
+ # Many hosts now default to a non-ASCII C locale, however, so
+ # they can set a charset encoding here if they need.
+ if { [ishost "*-*-cygwin*"] } {
+ setenv LC_ALL C.ASCII
+ setenv LANG C.ASCII
+ }
+
set blddir [lookfor_file [get_multilibs] libstdc++-v3]
set flags_file "${blddir}/scripts/testsuite_flags"
v3track flags_file 2